Pytorch深度学习入门与实战一--全连接神经网络

全连接神经网络在分类和回归问题中都非常有效,本节对全连接神经网及神经元结构进行介绍,并使用Pytorch针对分类和回归问题分别介绍全连接神经网络的搭建,训练及可视化相关方面的程序实现。
1.全连接神经网络简介

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler,MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score,confusion_matrix,calsaaification_report
from sklearn.manifold import TSNE
import torch
import torch.nn as nn
from torch.optim import SGD,Adam
from torch.utils.data as Data
import matplotlib.pyplot as plt
import seaborn as sns
import hiddenlayer as hl
from torchviz import make_dot

**2.MLP分类

  • 数据准备和探索
    本节使用一个垃圾邮件数据介绍如何使用PyTorch建立MLP分类模型,该数据集可以从UCI机器学习数据库进行下载。
https://archive.ics.uci.edu/ml/datasets/Spambase

该数据集中包含57个邮件内容的统计特征,其中:
48个特征是关键词出现的频率x100的取值,范围为[0,100],变量名使用word_freq_WORD命名,WORD表示该特征统计的词语。
6个特征为关键字符出现的频率x100取值,取值范围为[0,100],变量名为char_freq_CHAR命名
1个变量为captical_run_length_average,表示大写字母不间断的平均长度
1个变量captial_run_length_total表示邮件中大写字母的数量。
数据集中最后一个变量是带预测目标变量(0,1),表示电子邮件被认为是垃圾邮件(1)或者不是(0)

 spam=pd.read_csv("data/chap5/spambase.csv")
spam.head()
pd.value_counts(spam.label)

X=spam.iloc[:,0:57].values
y=spam.label.values
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=123)

scales=MinMaxScaler(featre_range=(0,1))
X_train_s=scales.fit_trandform(X_train)
X_test_s=scales.fit_trandform(X_test)

colname=spam.cloumns.values[:-1]
plt.figure(figsize=(20,14))
for ii in range(len(colname)):
    plt.subplot(7,9,ii+1)
    sns.boxplot(x=y_train,y=X_train_s[:,ii])
    plt.title(colname[ii])
plt.subplots_adjust(hspace=0.4)
plt.show()
  • 搭建网络并可视化
 class MLPclassifica(nn.Module):
    def __init__(self):
        super(MLPclassifica,self).__init__()
        self.hidden1=nn.Sequential(
            nn.Linear(
                in_features=57,
                out_features=30,
                bias=True,
            ),
            nn.ReLU()
        )
        self.hidden2=nn.Sequential(
            nn.Linear(30,10),
            nn.ReLU()
        )
        self.classifica=nn.Sequential(
            nn.Linear(10,2),
            nn.Sigmoid()
        )
    def forward(self,x):
        fc1=self.hidden1(x)
        fc2=self.hidden2(fc1)
        output=self.classifica(fc2)
        return fc1,fc2,output

mlpc=MLPclassifica()
x=torch.randn(1,57).reshapes_grad_(True)
y=mlpc(x)
Mymlpcvis=make_dot(y,params=dict(list(mlpc.named_parameters())+[('x',x)]))
Mymlpcvis
  • 使用未预处理的数据训练模型
X_train_nots=torch.from_numpy(X_train.astype(np.float32))
y_train_t=torch.from_numpy(y_train.astype(np.int64))
X_test_nots=torch.from_numpy(X_test.astype(np.float32))
y_test_t=torch.from_numpy(y_test.astype(np.int64))
train_data_nots=Data.TensorDataset(X_train_nots,y_train_t)
train_nots_loader=Data.DataLodaer(
    dataset=train_data_nots,
    batch_size=64,
    shuffle=True,
    num_workers=1,
)
optimizer=torch.optim.Adam(mlpc.parameters(),lr=0.01)
loss_func=nn.CrossEntropyLoss()

history1=h1.History()
canvas1=h1.Canvas()
print_step=25

for epoch in range(15):
    for step,(b_x,b_y) in enumerate(train_nots_loader):
        _,_,output=mlpc(b_x)
        train_loss=loss_func(output,b_y)
        optimizer.zero_grad()
        train_loss.backward()
        optimizer.step()
        niter=epoch*len(train_nots_loader)+step+1
        if niter % print_step == 0:
            _,_,output=mlpc(X_test_nots)
            _,pre_lab=torch.max(output,1)
            test_accuracy=accuracy_score(y_test_t,pre_lab)
            history1.log(niter,train_loss=train_loss,test_accuracy=test_accuracy)

            with canvas1:
                canvas1.draw_plot(history1["train_loss"])
                canvas1.draw_plot(history1["test_accuracy"])
  • 使用预处理的数据训练模型
X_train_t=torch.from_numpy(X_train_s.astype(np.float32))
y_train_t=torch.from_numpy(y_train.astype(np.int64))
X_test_t=torch.from_numpy(X_test_s.astype(np.float32))
y_test_t=torch.from_numpy(y_test.astype(np.int64))
train_data=Data.TensorDataset(X_train_t,y_train_t)
train_loader=Data.DataLodaer(
    dataset=train_data,
    batch_size=64,
    shuffle=True,
    num_workers=1,
)
optimizer=torch.optim.Adam(mlpc.parameters(),lr=0.01)
loss_func=nn.CrossEntropyLoss()

history1=h1.History()
canvas1=h1.Canvas()
print_step=25

for epoch in range(15):
    for step,(b_x,b_y) in enumerate(train_loader):
        _,_,output=mlpc(b_x)
        train_loss=loss_func(output,b_y)
        optimizer.zero_grad()
        train_loss.backward()
        optimizer.step()
        niter=epoch*len(train_loader)+step+1
        if niter % print_step == 0:
            _,_,output=mlpc(X_test_t)
            _,pre_lab=torch.max(output,1)
            test_accuracy=accuracy_score(y_test_t,pre_lab)
            history1.log(niter,train_loss=train_loss,test_accuracy=test_accuracy)

            with canvas1:
                canvas1.draw_plot(history1["train_loss"])
                canvas1.draw_plot(history1["test_accuracy"])

        _,_,output=mlpc(X_test_t)
        _,pre_lab=torch.max(output,1)
        test_accuracy=accuracy_score(y_test_t,pre_lab)
        print("test_accuracy:",test_accuracy) 
  • 获取中间层的输出并可视化

  • 使用中间层的输出

 _,test_fc2,_=mlpc(X_test_t)
print("test_fc2.shape: ",test_fc2.shape)
test_fc2_tsne=TSNE(n_components=2).fit_transform(test_fc2.data.numpy())
plt.figure(figsize=(8,6))
plt.xlim([min(test_fc2_tsne[:,0]-1),max(test_fc2_tsne[:,0])+1])
plt.ylim([min(test_fc2_tsne[:,1]-1),max(test_fc2_tsne[:,1])+1])
plt.plot(test_fc2_tsne[y_test==0,0],test_fc2_tsne[y_test=0,1],"bo",label="0")
plt.plot(test_fc2_tsne[y_test==1,0],test_fc2_tsne[y_test=1,1],"rd",label="1")
plt.legend()
plt.title("test_f2_tsne")
plt.show()
  • 使用钩子获取中间层的输出
activation={}
def get_activation(name):
    def hook(model,input,output):
        activation[name]=output.detach()
    return hook
mlpc.classifica.register_forward_hook(get_activation("classifica"))
_,_,_=mlpc(X_test_t)
classifica=activation["classifica"].data.numpy()
print("classifica.shape:"classifica.shape)
plt.figure(figsize=(8,6))
plt.plot(classifica[y_test==0,0],classifica[y_test=0,1],"bo",label="0")
plt.plot(classifica[y_test==1,0],classifica[y_test=1,1],"rd",label="1")
plt.legend()
plt.title("test_f2_tsne")
plt.show()

3.MLP回归模型

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler,MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error,mean_absolute_error
from sklearn.datasets import fetch_california_housing
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.optim import SGD
from torch.utils.data as Data
import matplotlib.pyplot as plt
import seaborn as sns

housdata=fetch_california_housing()
X_train,X_test,y_train,y_test=train_test_split(
    housdata.data,housdata.target,test_size=0.3,random_state=42
)
scale=StandardScaler()
X_train_s=scale.fit_transform(X_train)
X_test_s=scale.fit_transform(X_test)

housedatadf=pd.DataFrame(data=X_train_s,columns=housedata.feature_names)
housedatadf["target"]=y_train
//热力图分析9个变量之间的相关性
datacor=np.corrcoef(housedatadf.values,rowvar=0)
datacor=pd.DataFrame(data=datacor,columns=housedatadf.columns,index=housedatadf.columns)
plt.figure(figsiez=(8,6))
ax=sns.heatmap(datacor,square=True,annot=True,fmt=".3f",linewidths=.5,cmap="Y1GnBu",cbar_kws={"fraction":0.046,"pad""0.03"})
plt.show()

train_xt=torch.from_numpy(X_train_s.astype(np.float32))
train_yt=torch.from_numpy(y_trian.astype(np.float32))
test_xt=torch.from_numpy(X_test_s.astype(np.float32))
test_yt=torch.from_numpy(y_test.astype(np.float32))

train_data=Data.TensorDataset(train_xt,train_yt)
test_data=Data.TensorDataset(test_xt,test_yt)
train_loader=Data.DataLoader(dataset=train_data,batch_size=64,shuffle=True,num_workers=1)

class MPLregression(nn.Module):
    def __init__(self):
        super(MLPregression,self).__init__()
        self.hidden1=nn.Linear(in_features=8,out_features=100,bias=True)
        self.hidden2=nn.Linear(100,100)
        self.hidden3=nn.Linear(100,50)
        self.predict=nn.Linear(50,1)

    def forward(self,x):
        x=F.relu(self.hidden1(x))
        x=F.relu(self.hidden2(x))
        x=F.relu(self.hidden3(x))
        output=self.predict(x)
        return output[:,0]

mlpreg=MPLregression()
print(mlpreg)

optimzer=torch.optim.SGD(mlpreg.parameters(),lr=0.01)
loss_func=nn.MSELoss()
train_loss_all=[]
for epoch in range(30):
    train_loss=0
    train_num=0
    for step,(b_x,b_y) in enumerate(train_loader):
        output=mlpreg(b_x)
        loss=loss_func(output,b_y)
        optimzer.zero_grad()
        loss.backward()
        optimzer.step()
        train_loss+=loss.item()*b_x.size(0)
        train_num+=b_x.size(0)
    train_loss_all.append(train_loss/train_num)
    
plt.figure(figsize=(10,6))
plt.plot(train_loss_all,"ro-",label="Train loss")
plt.legend()
plt.grid()
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.show()

pre_y=mlpreg(test_xt)
pre_y=pre_y.data.numpy()
mae=mean_absolute_error(y_test,pre_y)

index=np.argsort(y_test)
plt.figure(figsize=(12,5))
plt.plot(np.arange(len(y_test)),y_test[index],"r",label="Original Y")
plt.scatter(np.arange(len(pre_y)),pre_y[index],s=3,c="b",label="Prediction")
plt.legend(loc="upper left")
plt.grid()
plt.xlabel("Index")
plt.ylabel("Y")
plt.show()

你可能感兴趣的:(笔记,python,深度学习,神经网络)