1、实验目的和要求
- 实现误差反向传播法的神经网络。
- 使用python绘制出精确度和损失值。
2、实验内容
输出使用后4000个样本训练得到模型在测试集上的结果
参数设置为:batch:300;iters_num: 2000;lamda:0.1
shiyan5.py
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# 读入数据
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
iters_num = 10000 # 适当设定循环的次数
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
train_loss_list = []
train_acc_list = []
test_acc_list = []
iter_per_epoch = max(train_size / batch_size, 1)
for i in range(iters_num):
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
# 计算梯度
# grad = network.numerical_gradient(x_batch, t_batch)
grad = network.gradient(x_batch, t_batch)
# 更新参数
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train)
test_acc = network.accuracy(x_test, t_test)
train_acc_list.append(train_acc)
test_acc_list.append(test_acc)
print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))
# 绘制图形
markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
train_neuralnet.py
# coding: utf-8
import sys, os
from matplotlib import pyplot as plt
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
'''以二层神经网络类TwoLayerNet为对象,使用MNIST数据集进行学习'''
# 读入数据
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
#x_train=x_train[-4000:]
# x_test=x_test[-4000:]
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
iters_num = 2000#表示更新次数
train_size = x_train.shape[0]#训练数据总数目
batch_size = 300#每次使用的批数据的大小
learning_rate = 0.1#学习率的大小
train_loss_list = []
train_acc_list = []#定义一个列表变量,用于记录每个epoch,训练数据的精度
test_acc_list = []#定义一个列表变量,用于记录每个epoch,测试数据的精度
iter_per_epoch = max(train_size / batch_size, 1)
setp=0
for i in range(iters_num):
setp=i
# 获取mini-batch
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
# 梯度
## 利用数值微分,计算出损失函数关于各个权重参数的梯度
#grad = network.numerical_gradient(x_batch, t_batch)
## 利用误差反向传播法,高效地计算出损失函数关于各个权重参数的梯度
grad = network.gradient(x_batch, t_batch)
# 更新
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
# 记录学习过程
# 计算每个epoch的识别精度
#一个 epoch 表示学习中所有训练数据均被使用过一次时的更新次数。
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train)## 计算训练数据的识别精度
test_acc = network.accuracy(x_test, t_test)## 计算测试数据的识别精度
train_acc_list.append(train_acc)## 将计算出的识别精度存放至各自的列表
test_acc_list.append(test_acc)
print("step :"+str(setp)+" train acc, test acc | " + str(train_acc) + ", " + str(test_acc))
#印出训练数据和测试数据的识别精度(用于比较,观察是否存在过拟合现象)
#绘制图像
x = np.arange(len(train_acc_list)) # 设置x为精度数组下标
plt.plot(x, train_acc_list, label='train acc') # 以训练数据精度数组的值为y,绘制标签为'train acc'的曲线
plt.plot(x, test_acc_list, label='test acc', linestyle='--') # 以测试数据精度数组的值为y,用虚线绘制标签为'test acc'的曲线
plt.xlabel("epochs") # 设置x轴标签为"epochs"
plt.ylabel("accuracy") # 设置y轴标签为"accuracy"
plt.ylim(0, 1.0) # 设置y轴的范围为0到1
plt.legend(loc='lower right') # 设置图例,控制其在图像右下角
plt.show()
# 显示图像
#损失函数画图
x1 = np.arange(0,iters_num)#
plt.plot(x1, train_loss_list, label='test acc', linestyle='--')
plt.show()
'''
实线表示训练数据的识别精度,虚线表示测试数据的识别精度。如图所示,随着 epoch 的前进(学习的进行),
我们发现使用训练数据和测试数据评价的识别精度都提高了,
并且,这两个识别精度基本上没有差异(两条线基本重叠在一起)。
因此,可以说这次的学习中没有发生过拟合的现象。
'''
two_layer_net.py
# coding: utf-8
import sys, os
from matplotlib import pyplot as plt
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
'''以二层神经网络类TwoLayerNet为对象,使用MNIST数据集进行学习'''
# 读入数据
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
# x_train=x_train[-4000:]
# x_test=x_test[-4000:]
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
iters_num = 2000 # 表示更新次数
train_size = x_train.shape[0] # 训练数据总数目
batch_size = 300 # 每次使用的批数据的大小
learning_rate = 0.1 # 学习率的大小
train_loss_list = []
train_acc_list = [] # 定义一个列表变量,用于记录每个epoch,训练数据的精度
test_acc_list = [] # 定义一个列表变量,用于记录每个epoch,测试数据的精度
iter_per_epoch = max(train_size / batch_size, 1)
setp = 0
for i in range(iters_num):
setp = i
# 获取mini-batch
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
# 梯度
## 利用数值微分,计算出损失函数关于各个权重参数的梯度
# grad = network.numerical_gradient(x_batch, t_batch)
## 利用误差反向传播法,高效地计算出损失函数关于各个权重参数的梯度
grad = network.gradient(x_batch, t_batch)
# 更新
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
# 记录学习过程
# 计算每个epoch的识别精度
# 一个 epoch 表示学习中所有训练数据均被使用过一次时的更新次数。
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train) ## 计算训练数据的识别精度
test_acc = network.accuracy(x_test, t_test) ## 计算测试数据的识别精度
train_acc_list.append(train_acc) ## 将计算出的识别精度存放至各自的列表
test_acc_list.append(test_acc)
print("step :" + str(setp) + " train acc, test acc | " + str(train_acc) + ", " + str(test_acc))
# 印出训练数据和测试数据的识别精度(用于比较,观察是否存在过拟合现象)
# 绘制图像
x = np.arange(len(train_acc_list)) # 设置x为精度数组下标
plt.plot(x, train_acc_list, label='train acc') # 以训练数据精度数组的值为y,绘制标签为'train acc'的曲线
plt.plot(x, test_acc_list, label='test acc', linestyle='--') # 以测试数据精度数组的值为y,用虚线绘制标签为'test acc'的曲线
plt.xlabel("epochs") # 设置x轴标签为"epochs"
plt.ylabel("accuracy") # 设置y轴标签为"accuracy"
plt.ylim(0, 1.0) # 设置y轴的范围为0到1
plt.legend(loc='lower right') # 设置图例,控制其在图像右下角
plt.show()
# 显示图像
# 损失函数画图
x1 = np.arange(0, iters_num) #
plt.plot(x1, train_loss_list, label='test acc', linestyle='--')
plt.show()
'''
实线表示训练数据的识别精度,虚线表示测试数据的识别精度。如图所示,随着 epoch 的前进(学习的进行),
我们发现使用训练数据和测试数据评价的识别精度都提高了,
并且,这两个识别精度基本上没有差异(两条线基本重叠在一起)。
因此,可以说这次的学习中没有发生过拟合的现象。
'''