深度学习入门-基于python的理论与实现5

本文介绍了如何在Python中使用TwoLayerNet类构建一个包含隐藏层的神经网络,并通过numerical_gradient函数实现损失函数的梯度计算。重点在于理解如何利用数值微分方法计算权重参数对损失函数的影响,以及函数内部参数修改对函数外部的影响。
摘要由CSDN通过智能技术生成

现在我们来搭建一个两层的神经网络

import sys,os
sys.path.append(os.pardir)
from common.functions import *
from common.gradient import numerical_gradient
from dataset.mnist import  load_mnist


class 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)+b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1,W2)+b2
        y = softmax(a2)
        return y

    def 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 accuracy

    def 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


net = TwoLayerNet(input_size=784,hidden_size=100,output_size=10)

(x_train,t_train),(x_test,t_test) = load_mnist(normalize = True,one_hot_label=True)
# print(net.params['W1'].shape)# (784,100)
# print(net.params['b1'].shape)#(100)
# print(net.params['W2'].shape)#(100,10)
# print(net.params['b2'].shape)#(10)
#
print(net.numerical_gradient(x_train,t_train))

个人感觉loss 还不是很完善,

print(net.numerical_gradient(x_train,t_train))

传入训练数据和标签,求的是网络的梯度。

 grads['W1'] = numerical_gradient(loss_W,self.params['W1'])

上面这个代码的 numerical_gradient 是在另一个文件里定义的。

定义如下:

def numerical_gradient(f, x):  # f是loss,x是权重w
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h  #在这里 w 被修改了,x 就是w

        fxh1 = f(x) # f(x+h)   ,
        # 这里 f(W)其实就是 loss(x,y)
        #在这里会改变函数外参数的值
        # loss(x,y)里面有个predict 让修改的w和x相乘
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val # 还原值
        it.iternext()   
        
    return grad

这个时候发现问题了:

 grads['W1'] = numerical_gradient(loss_W,self.params['W1'])

loss_W 是f,self.params['W1']是 x

然后求 f(x),也就是 loss_W(x),  但是

loss_W 需要两个参数,而 只传入一个self.params['W1'] 。

f = lambda w: net.loss(x, t)  # 定义函数f
等价于
def f(w):
	return net.loss(x, t)

再顺一遍发现,求的梯度是  x  和  t  的差距 

w和损失函数只有间接关系。

参考了:(19条消息) 解析深度学习入门代码f = lambda w: net.loss(x, t)_嘻嘻作者哈哈的博客-CSDN博客https://blog.csdn.net/weixin_43971252/article/details/109066536

但是他说每次predict用的是修改过的w,但是这个代码里,没看到W修改 

 x[idx] = float(tmp_val) + h  #在这里 w 被修改了,而且函数外的w也被修改了
 fxh1 = f(x) # f(x+h)   ,
        # 这里 f(W)其实就是 loss(x,y)
        #当传入的是字典型,列表型时如果是重新对其赋值则不会改变函数外参数的值,如果是进行操作,则会改变
        #https://blog.csdn.net/liuxiao214/article/details/81673093
        # loss(x,y)里面有个predict  。它让修改的w和x相乘

至于w是怎么修改的,建议看下面完整版,代码。因为没看给的源码,走了好多弯路,(有更新的语句,书上在前面提到了,但是写这个类的时候没给出来,,浪费一天看这个。。。拉跨)


# 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()


关于python函数内改变参数的值  是否会影响到函数外的参数


def change(x):
    x[0] = x[0]+1

def change2(x):
    x['W'] = x['W']+1

def change3(x):
    x['W'] = 5

a = [0,1,2]
print(a)
change(a)
print(a)
'''
[0, 1, 2]
[1, 1, 2]

'''

b = {'W':2,'b':3}
print(b)
change2(b)
print(b)

'''
{'W': 2, 'b': 3}
{'W': 3, 'b': 3}
'''

c = {'W':3,'b':3}
print(c)
change3(c)
print(c)
'''
{'W': 3, 'b': 3}
{'W': 5, 'b': 3}
'''

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 深度学习是一种机器学习技术,可以通过模拟人类大脑的神经网络结构来实现智能决策和预测。Python是一种广泛使用的编程语言,也是深度学习中使用最多的语言之一。 如果你想入门深度学习并使用Python进行实现,可以参考一些经典的教材和资源,例如《Python深度学习》(Francois Chollet著)、《深度学习入门:基于Python理论实现》(斋藤康毅著)等。这些教材通常会介绍深度学习的基础理论Python的基本语法和深度学习框架(如TensorFlow、Keras等)的使用方法,同时也会提供一些实例代码和练习题帮助你快速上手。 此外,你也可以通过在线课程和MOOC平台学习深度学习Python编程。例如,Coursera、Udacity和edX等平台都提供了相关课程,可以根据自己的需求和兴趣进行选择。 ### 回答2: 深度学习入门:基于Python理论实现,是一本介绍深度学习的较为全面的教程。本书主要介绍了人工神经网络,包括基于反向传播算法的多层感知器、卷积神经网络、循环神经网络等基本模型以及它们的实现方法,同时还介绍了一些高级话题,如深度强化学习、生成模型等等。 在本书中,作者通过大量的编程实例来演示深度学习的应用。这些实例包括用深度学习算法进行手写数字识别、图像分类、语音识别和自然语言处理等任务。由于Python是目前流行的机器学习工具之一,因此这本书的实现过程都使用了Python编程语言。 具体来说,本书的主要内容包括人工神经网络基础知识、多层感知器模型、卷积神经网络模型、循环神经网络模型、生成模型、 强化学习、深度学习框架等方面,同时还包括很多深度学习的应用案例。作者采用了基础理论、数学公式、实例程序和实验数据等不同形式的阐释方法,使读者既能够理解深度学习的基本原理,也能够掌握它的实现方法。 此外,本书还提供了大量的参考文献和网上资源,使读者可以进一步深入学习和研究深度学习。在阅读本书的同时,读者可以根据作者提供的代码和数据,通过实际操作来进一步巩固理论知识和应用技能。 总之,深度学习入门:基于Python理论实现是一本非常实用的深度学习教材,可以帮助初学者更好地了解深度学习的基本概念和方法,提高实际应用的技能。 ### 回答3: 深度学习是一种人工智能技术,可用于训练计算机识别和理解大量数据。《深度学习入门:基于Python理论实现》这本书是入门者学习深度学习的必读之书。以下是本书的内容概述。 本书的第一部分介绍了深度学习的基础概念和理论,包括神经网络、反向传播算法、损失函数等。介绍了基本的深度学习模型,如前馈神经网络、卷积神经网络和循环神经网络。此外,还介绍了优化算法和正则化技术。 在第二部分中,作者使用Python编程语言实现了各种深度学习模型,使用的是许多广泛使用的深度学习框架,如TensorFlow和PyTorch。学习者获得从头开始编写深度学习算法的经验,同时实际应用中必备的PyTorch和TensorFlow经验。 在第三部分中,本书涵盖了几个应用案例,包括图像分类、语音识别和自然语言处理。幸运的是,这些案例通过代码演示展示,确保即使您没有实际应用经验也能操作成功。 总的来说,《深度学习入门:基于Python理论实现》是一本适合想要学习深度学习的初学者的绝佳书籍。其提供了深度学习的基本理论和核心技术,同时应用Python编程语言演示了实现技术。由此学习者可以建立深度学习专业的技术栈和能力,在人工智能领域有更广阔的发展空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值