目录
Exercise 4: Neural Networks Learning
Exercise 4: Neural Networks Learning
需要用到的库
import numpy as np
import scipy.io
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
1. Neural Networks模型
输入的数据为5000x400,共有10个类别,神经网络共有3层,输入层大小为400,输出层大小为10,隐藏层大小为25。第一个隐藏层的激活函数可以是sigmoid或者relu,第二个隐藏层的激活函数为softmax。后面会对不同的激活函数进行比较,也会对不同隐藏层大小进行比较。
input_layer_size = 400 # 20x20 Input Images of Digits
hidden_layer_size = 25 # 25 hidden units
num_labels = 10 # 10 labels, from 1 to 10
class NeuralNetworks(nn.Module):
def __init__(self):
super(NeuralNetworks, self).__init__()
self.linear1 = nn.Linear(input_layer_size, hidden_layer_size)
self.linear2 = nn.Linear(hidden_layer_size, num_labels)
self.relu = nn.ReLU()
self.softmax = nn.Softmax(dim=1)
nn.init.xavier_normal_(self.linear1.weight, gain=0.01)
nn.init.xavier_normal_(self.linear2.weight, gain=0.01)
nn.init.constant_(self.linear1.bias, 0)
nn.init.constant_(self.linear2.bias, 0)
def forward(self,x):
out = self.linear1(x)
out = self.relu(out)
out = self.linear2(out)
out = self.softmax(out)
return out
2. 加载数据
加载并展示数据,如下图所示。
3. 网络训练
选择的模型为定义好的模型,损失函数为交叉熵函数,优化器选择Adam优化,如果有GPU的话,将训练数据、标签和模型都放在GPU上,可以加快训练速度。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = NeuralNetworks()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-2, weight_decay=0)
X_t = torch.from_numpy(X).type(torch.FloatTensor).to(device)
y_t = torch.from_numpy(y).type(torch.LongTensor).to(device)
model = model.to(device)
网络迭代500次,损失函数和准确率变化如图所示。
best_precision = 0
train_loss_curve =[]
train_precision_curve =[]
for epoch in range(500):
model.train()
y_pred = model(X_t)
loss = criterion(y_pred, y_t)
print(epoch, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss_curve.append(loss.item())
model.eval()
y_pred = model(X_t).cpu().detach().numpy()
y_pred = np.argmax(y_pred, axis=1)
precision = np.mean(y_pred == y) * 100
train_precision_curve.append(precision)
if precision > best_precision:
best_precision = precision
损失函数变化曲线
准确率变化曲线
4.结果比较
4.1 激活函数比较
比较使用relu或者sigmoid两个函数激活,对数据准确率的影响,影响的只是在本数据集上的准确率,不同的数据集需要进行相应的分析。从下表可以看出relu准确率稍低。
relu | sigmoid | |
---|---|---|
precision | 97.3% | 98.04% |
4.2 隐藏层个数比较
设置不同隐藏层个数,查看隐藏层个数对准确率的影响,使用的激活函数为relu。
Number | Precision |
---|---|
25 | 97.3% |
100 | 97.7% |
250 | 98.4% |
1000 | 98.58% |
2000 | 98.9% |
激活层为sigmoid时,隐藏层个数对准确率的影响如下表所示。
Number | Precision |
---|---|
25 | 98.04% |
100 | 98.66% |
250 | 88.94% |
1000 | 89.14% |
使用sigmoid函数,当隐藏层增多时,结果并不稳定,可能是出现了梯度消失的现象,使用relu没有出现此现象,说明relu可以缓解梯度消失的现象。