
使用神经网络解决问题_螺旋数据集
x 是输入数据,t 是监督标签。观察 x 和 t 的形状,可知它们各自有 300 笔样本数据,其中 x 是二维数据,t 是三维数据。另外,t 是 one-hot 向量,对应的正确解标签的类标记为 1,其余的标记为 0。下面,我们把这些数据绘制在图上,结果如图 1-31 所示。现在,我们来实现一个具有一个隐藏层的神经网络。首先,import 语句和初始化程序的 init() 如下所示初始化程序接收
1 螺旋数据集
import sys
sys.path.append('..') # 为了引入父目录的文件而进行的设定
from dataset import spiral
import matplotlib.pyplot as plt
x, t = spiral.load_data()
print('x', x.shape) # (300, 2)
print('t', t.shape) # (300, 3)
x 是输入数据,t 是监督标签。观察 x 和 t 的形状,可知它们各自有 300 笔样本数据,其中 x 是二维数据,t 是三维数据。另外,t 是 one-hot 向量,对应的正确解标签的类标记为 1,其余的标记为 0。
下面,我们把这些数据绘制在图上,
# 绘制数据点
N = 100
CLS_NUM = 3
markers = ['o', 'x', '^']
for i in range(CLS_NUM):
plt.scatter(x[i*N:(i+1)*N, 0], x[i*N:(i+1)*N, 1], s=40, marker=markers[i])
plt.show()
结果如图 1-31 所示。
2 神经网络的实现
现在,我们来实现一个具有一个隐藏层的神经网络。首先,import 语句和初始化程序的__init__() 如下所示
import sys
sys.path.append('..')
import numpy as np
from common.layers import Affine, Sigmoid, SoftmaxWithLoss
class TwoLayerNet:
def __init__(self, input_size, hidden_size, output_size):
I, H, O = input_size, hidden_size, output_size
# 初始化权重和偏置
W1 = 0.01 * np.random.randn(I, H)
b1 = np.zeros(H)
W2 = 0.01 * np.random.randn(H, O)
b2 = np.zeros(O)
# 生成层
self.layers = [
Affine(W1, b1),
Sigmoid(),
Affine(W2, b2)
]
self.loss_layer = SoftmaxWithLoss()
# 将所有的权重和梯度整理到列表中
self.params, self.grads = [], []
for layer in self.layers:
self.params += layer.params
self.grads += layer.grads
初始化程序接收 3 个参数。input_size 是输入层的神经元数,hidden_size 是隐藏层的神经元数,output_size 是输出层的神经元数。在内部实现中,首先用零向量(np.zeros())初始化偏置,再用小的随机数(0.01 * np.random.randn())初始化权重。通过将权重设成小的随机数,学习可以更容易地进行。接着,生成必要的层,并将它们整理到实例变量 layers 列表中。最后,将这个模型使用到的参数和梯度归纳在一起。
接着,我们为 TwoLayerNet 实现 3 个方法,即进行推理的 predict() 方法、正向传播的 forward() 方法和反向传播的 backward() 方法
def predict(self, x):
for layer in self.layers:
x = layer.forward(x)
return x
def forward(self, x, t):
score = self.predict(x)
loss = self.loss_layer.forward(score, t)
return loss
def backward(self, dout=1):
dout = self.loss_layer.backward(dout)
for layer in reversed(self.layers):
dout = layer.backward(dout)
return dout
如上所示,这个实现非常清楚。因为我们已经将神经网络中要用的处理模块实现为了层,所以这里只需要以合理的顺序调用这些层的 forward() 方法和 backward() 方法即可。
更多推荐
所有评论(0)