全连接神经网络在分类和回归问题中都非常有效,本节对全连接神经网及神经元结构进行介绍,并使用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分类
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()