开始机器学习
- 机器学习的hello word–手写数字识别
- 语言–python
- 环境/平台–colab
colab介绍
谷歌免费的GPU资源,但是要*,你有谷歌账号就行,具体使用方法自行百度。
cd需要加%才能使用
其他的加!使用
例如:
%cd drive/MyDrive/Colab\ Notebooks
!pwd
开始吧
1.导入一些库
import numpy as np #针对数组运算提供大量的数学函数库
import scipy.special #字符串切片用
import matplotlib.pyplot #画图
2.神经网络的结构
class class neuralNetwork:
#初始化函数
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
#训练函数
def train(self,inputs_list,targets_list):
#预测函数/查询函数 //喜欢怎么叫就怎么叫吧
def query(self,inputs_list):
3.函数的实现
- 3.1初始化函数:
因为是第一次,所以用一个非常简单的神经网络,只有三层,输入层1,隐藏层1,输出层1。
所以初始化时必须先定义一下这些层,同时需要定义学习率(learning rate),激活函数(activation function)。当然,还要初试化权重。
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
#neural number 每一层神经元数量
self.inodes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
#learning rate 学习率 //我的理解是每次更新权重参数的步长
self.lr = learningrate
#weights 权重
self.wih=(np.random.rand(self.hnodes,self.inodes)-0.5)
self.who=(np.random.rand(self.onodes,self.hnodes)-0.5)
#activation function 激活函数 sigmoid
self.activation_function = lambda x:scipy.special.expit(x)
- 3.2训练函数:
优化方法是SGD(随机梯度下降法),计算梯度利用了反向传播法(直接从前往后算梯度非常复杂,而从后向前则简单很多 就是链式法则//具体理解请自行搜索)。
def train(self,inputs_list,targets_list):
#将输入转为二维矩阵
inputs = np.array(inputs_list,ndmin=2).T #输入的28*28个数
targets = np.array(targets_list,ndmin=2).T#标签 即正确的数
#前向传播
hidden_inputs = np.dot(self.wih,inputs)
hidden_outputs=self.activation_function(hidden_inputs)
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs)
#反向传播 更新权重
output_errors=targets - final_outputs
hidden_errors=np.dot(self.who.T,output_errors)
self.who += self.lr*np.dot((output_errors*final_outputs*(1.0-final_outputs)),np.transpose(hidden_outputs))
self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)),np.transpose(inputs))
pass
- 3.3查询函数:
这就很简单了,将数据输入,根据权重直接计算结果。
def query(self,inputs_list):
#将输入转为二维矩阵
inputs = np.array(inputs_list,ndmin=2).T
#print(inputs)
#输入乘以第一层权重
hidden_inputs = np.dot(self.wih,inputs)
#通过激活函数输出
hidden_outputs=self.activation_function(hidden_inputs)
#最后一层,和前面一样
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs)
return final_outputs
- 3.4整体神经网络代码:
import numpy as np
import scipy.special
import matplotlib.pyplot
class neuralNetwork:
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
self.inodes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
self.lr = learningrate
#weights
self.wih=(np.random.rand(self.hnodes,self.inodes)-0.5)
self.who=(np.random.rand(self.onodes,self.hnodes)-0.5)
#activation function
self.activation_function = lambda x:scipy.special.expit(x)
pass
def train(self,inputs_list,targets_list):
#将输入转为二维矩阵
inputs = np.array(inputs_list,ndmin=2).T
targets = np.array(targets_list,ndmin=2).T
hidden_inputs = np.dot(self.wih,inputs)
hidden_outputs=self.activation_function(hidden_inputs)
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs)
output_errors=targets - final_outputs
hidden_errors=np.dot(self.who.T,output_errors)
self.who += self.lr*np.dot((output_errors*final_outputs*(1.0-final_outputs)),np.transpose(hidden_outputs))
self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)),np.transpose(inputs))
pass
def query(self,inputs_list):
#将输入转为二维矩阵
inputs = np.array(inputs_list,ndmin=2).T
#print(inputs)
#输入乘以第一层权重
hidden_inputs = np.dot(self.wih,inputs)
#通过激活函数输出
hidden_outputs=self.activation_function(hidden_inputs)
#最后一层,和前面一样
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs)
return final_outputs
pass
4.跑数据训练它:
经典的mnist数据集,直接跑,也不管小批量了好吧,第一次能成就行,直接整个数据跑。7个epoch用时7-8分钟。
#神经元数量
input_nodes = 784
hidden_nodes = 200
output_nodes = 10
#学习率
lr=0.2
#初始化神经网络
n=neuralNetwork(input_nodes,hidden_nodes,output_nodes,lr)
#打开并读取数据集
training_data_file= open("mnist_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close
#跑7个epoch
for e in range(7):
#每一笔数据取出后将标签拿出来,其他的传给训练函数
for record in training_data_list:
all_values = record.split(',')
inputs=(np.asfarray(all_values[1:])/255.0 *0.99)+0.01
targets = np.zeros(output_nodes)+0.01
targets[int(all_values[0])]=0.99
n.train(inputs,targets)
pass
pass
5.训练完成后进行测试:
#记录正确与否
scorecard = []
#打开并读取数据
test_data_file = open("mnist_test.csv",'r')
test_data_list = test_data_file.readlines()
test_data_file.close()
#测试
for re in test_data_list:
all_values = re.split(',')
#获取正确的标签
correct_lable = int (all_values[0])
#print(correct_lable,"correct lable")
inputs = (np.asfarray(all_values[1:])/255.0*0.99)+0.01
outputs = n.query(inputs)
lable = np.argmax(outputs)
# print(lable,"network's answer")
#正确就写1,否写0
if (lable == correct_lable):
scorecard.append(1)
else:
scorecard.append(0)
scorecard_array = np.asarray(scorecard)
#计算正确率
print("正确率:",scorecard_array.sum()/scorecard_array.size*100,'%')
6.结果还不错,96了。当然,我这是作弊的,学习率没有自己试,而是借鉴了前辈们的,哈哈哈。
感谢观看,后续学习继续更新,奥利给,xdm!