当前位置: 首页 > news >正文

深度学习入门-第4章-神经网络的学习

学习就是从训练数据中自动获取最优权重参数的过程。引入损失函数这一指标,学习的目的是找出使损失函数达到最小权重参数。使用函数斜率的梯度法来找这个最小值。

人工智能有两派,一派认为实现人工智能必须用逻辑和符号系统,自顶向下看问题;另一派认为通过仿造人脑可以达到人工智能,自底向上看问题。前一派是“想啥来啥”,后一派是“吃啥补啥”。前者偏唯心,后者偏唯物。两派一直是人工智能领域“两个阶级、两条路线”的斗争,这斗争有时还是你死我活。今天学习的是神经网络派。

4.1 从数据中学习

4.1.1 数据驱动

数据是机器学习的命根子。机器学习避免人为介入,通过数据发现模式。比如识别手写数字5,可以从图像中提取特征量,再用机器学习学习这些特征量的模式。其中图像转换为向量时使用的特征量仍由人设计,不同问题需要人工考虑不同的特征量。

神经网络(深度学习)称为端到端学习,图像中的特征量也由机器来学习。不管识别5还是识别狗,神经网络都是通过不断学习数据,尝试发现模式。

4.1.2 训练数据和测试数据

追求的模型泛化能力。训练数据也叫监督数据。一套数据集,无法获得正确的评价。要避免对某数据集的过拟合

4.2 损失函数

损失函数表示神经网络恶劣程度指标。一般乘上一个负值。

4.2.1 均方误差

4.2.2 交叉熵误差

4.2.3 mini-batch学习

从训练数据中选出小批量学习,称为mini-batch学习。随机选择小批量做为全体训练数据的近似值。

4.2.4 mini-batch版交叉熵误差实现

4.2.5 为何要设定损失函数

为了找到使损失函数值尽可能小的地方,需要计算参数导数,以导数为指引,逐步更新参数值。

对权重参数的损失函数求导,表示的是:如果稍微改变这个权重的值,损失函数的值如何变化

1)导数为负,权重参数正向变化,可以减小损失函数的值。

2)导数为正,权重参数负向变化,可以减小损失函数的值。

3)导数为0,权重参数哪个方向变化,损失函数都不变化。

不能直接使用识别精度,是因为大部分地方的参数导数为0,导致参数无法更新。

为啥是0?比如识别精度为32%, 微调权重参数,识别精度仍旧是32%,即使改变,也不会联系变化,而是33%,34%等离散值。而损失函数会连续变化。作为激活函数的阶跃函数也有类似特征,大部分地方导数为0,所以不能使用阶跃函数,要使用斜率连续变化的sigmoid函数。

4.3 数值微分

什么是梯度。

4.3.1 导数

采用中心差分

(f(x+h)-f(x-h))/(2*h)

利用微小的差分求导的过程称为数值微分numerical differentiation

数学公式推导求导称为解析性求导。如y=^X{^{^{2}}} 公式求导为\frac{dy}{dx}=2x,这样算出的是没有误差的真导数

4.3.2 数值微分的例子

数值微分的计算结果和真导数误差很小。

4.3.3 偏导数

有两个变量的情况。或者多个变量。有多个变量的函数的导数称为偏导数

偏导数将多个变量中的某个变量定为目标变量,其他变量固定为某个值

4.4 梯度

由全部变量的偏导数汇总而成的向量称为梯度(gradient)

4.4.1 梯度法

使用梯度寻找损失函数最小值的方法就是梯度法。梯度是各点处函数值减小最多的方向。方向往往不是函数的最小值。是极小值。

不断沿梯度方向前进,逐渐减小函数值的过程,叫梯度法 gradient method

学习率:一次学习,在多大程度上更新参数。

梯度下降法实现:

def gradient_descent(f, init_x, lr=0.01,step_num=100):x = init_xfor i in range(step_num):grad = numerical_gradient(f,x)x -= lr * gradreturn x

4.4.2 神经网络的梯度

神经网络梯度:损失函数关于权重参数的梯度。形状与W相同。

求梯度代码

import sys,os
sys.path.append(os.pardir)
import numpy as np
from common.functions import softmax,cross_entropy_error
from common.gradient  import numerical_gradientclass simpleNet:def __init__(self):self.W = np.random.randn(2,3)def predict(self,x):return np.dot(x,self.W)def loss(self,x,t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y,t)return loss

4.5 学习算法的实现

4.5.1 二层神经网络类

#two_layer_net.py
import sys,os
sys.path.append(os.pardir)
from common.functions import *
from common.gradient import numerical_gradientclass TwoLayerNet:def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):self.params = {}self.params['W1'] = weight_init_std * np.random.randn(input_size,hidden_size)self.params['b1'] = np.zeros(hidden_size)self.params['W2'] = weight_init_std * np.random.randn(hidden_size,output_size)self.params['b2'] = np.zeros(output_size)def predict(self,x):W1,W2 = self.params['W1'], self.params['W2']b1,b2 = self.params['b1'], self.params['b2']a1 = np.dot(x,W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1,W2) + b2y = softmax(a2)return ydef loss(self, x, t):y = self.predict(x)return cross_entropy_error(y,t)def accuracy(self,x,t):y = self.predict(x)y = np.argmax(y, axis=1)t = np.argmax(t, axis=1)accuracy = np.sum(y==t)/float(x.shape[0])return accuracydef numerical_gradient(self,x,t):loss_W = lambda W:self.loss(x,t)grads = {}grads['W1'] = numerical_gradient(loss_W, self.params['W1']grads['b1'] = numerical_gradient(loss_W, self.params['b1']grads['W2'] = numerical_gradient(loss_W, self.params['W2']grads['b2'] = numerical_gradient(loss_W, self.params['b2']return grads

4.5.2  mini-batch学习

# train_neuralnet.py
import numpy as np
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)
train_loss_list=[]#超参数
iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
network = TwoLayerNet(input_size=784,hidden_size=50,output_size=10)
for i in range(iters_num):# 获取mini-batchbatch_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)

4.5.3 基于测试数据评价

epoch是一个单位,所有训练数据被使用一次时的更新次数。10000训练数据,mini-batch为100,共执行梯度下降法10000/100=100次,100次就是一个epoch

import numpy as np
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)
train_loss_list = []
train_acc_list = []
test_acc_list = []
#平均每个epoch的重复次数
iter_per_epoch = max(train_size/batch_size,1)
#超参数
iters_num = 10000
batch_size=100
learning_rate=0.1
network=TwoLayerNet(input_size=784,hidden_size=50,output_size=10)
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)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的识别精度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))


http://www.mrgr.cn/news/8849.html

相关文章:

  • 【redis】包含部署+主从复制+高可用+cluster
  • 每天一个数据分析题(四百八十九)- 主成分分析与因子分析
  • 【WebSocket】websocket学习【一】
  • Redis Stream 助力:打造实时用户行为日志处理平台
  • LINUX环境中宝塔Python虚拟环境变量问题
  • SQL Server 2017上服务端设置强制加密启用SSL
  • 利用VSCode正则方式捕获组替换,编码效率一飞冲天
  • 无人机遥控器里的接收器工作原理解析!
  • 美国RAKsmart大带宽服务器机房要求
  • 【 云原生应用的监控与日志管理】使用Prometheus、ELK Stack等工具进行云原生应用的监控与日志管理
  • Golang | Leetcode Golang题解之第365题水壶问题
  • 驾驭ASP.NET MVC:C# Web开发的精粹
  • DOM的概念及作用
  • Spring模块详解Ⅱ
  • 常用设计模式
  • 输入x的值,计算x的平方并赋值给y 分别以 y = x * x和 x * x = y 的形式输出x和y的值。
  • 零基础5分钟上手亚马逊云科技-利用MQ为应用解耦
  • ansible模块
  • 力扣:二叉树的前序遍历
  • ubuntu20.04配置open3D(C++常用API安装)