《深度学习入门》鱼书学习笔记(代码可运行)

本文介绍了配置深度学习环境的步骤,包括安装Anaconda、Pycharm,创建和管理虚拟环境,安装CUDA和cudnn以加速计算,以及在不同环境中安装Pytorch和tensorflow。同时,讲解了基础的Python语法、感知机模型和神经网络的相关概念,如激活函数和多层神经网络的实现。
摘要由CSDN通过智能技术生成

X、前言

X.1环境配置

x.1.1安装Anaconda

直接官网下载Anaconda,安装完成后,conda -V查看是否安装成功

activate-->进入base环境

conda create -n py37 python=3.7 创建一个叫py37的python3.7的虚拟环境

conda activate py37 进入py37虚拟环境

conda deactivate 退出一层虚拟环境

x.1.2安装Pycharm

直接官网下载社区版,安装Pycharm

安装成功后,打开创建一个新的Project,存储路径自己选

点击File-->settings-->project:PythonProject(可能就是项目名称)

点击小齿轮就可以Add解释器啦,找到Anaconda的安装文件,在envs中找到py37这个虚拟环境,将其中的python.exe文件添加到解释器中,这里就有解释器用啦

执行一个程序,运行成功,表示解释器在工作了。

x.1.3 安装CUDA与cudnn

英伟达为了使其GPU在深度学习上进行张量运算,推出了CUDA,确保系统中没有CUDA相关应用后,到CUDA官网下载适配显卡的CUDA版本,进行下载

安装CUDA,不要修改安装路径,并且对于三个要设置路径的安装部分来说,自己创建CUDA11.1文件夹,并在其中新建CUDA1与CUDA2文件夹,将前两个部分的安装路径设置到CUDA1下,将第三个部分的安装路径和设置到CUDA2下,安装即可

cudnn是一个基于CUDA的神经网络加速器,直接在官网找到对应版本,解压后将文件夹复制到CUDA1下即可

安装完成后用ncvv -V检查是否成功

x.1.4安装Pytorch

在刚刚的py37虚拟环境中安装Pytorch,激活到该虚拟环境中即可,找到有效的镜像源,直接pip install安装即可

x.1.5安装tensorflow

新建一个虚拟环境tf2,在该环境中安装tensorflow,直接用有效的镜像源安装即可,注意版本适配性

这样,就拥有了Pytorch与tensorflow两个不同虚拟环境了,在Pycharm中选择不同的虚拟环境下的解释器,就可以使用不同框架玩转深度学习啦

X.2注意事项

一、基础语法

#类
class Man:
    def __init__(self,name):
        self.name = name
        print("Initialized!")
        
    def hello(self):
        print("Hello" + self.name + "!")
        
    def goodbye(self):
        print("Good-bye" + self.name + "!")
        
m = Man("David")
m.hello()
m.goodbye()

# 基础绘图
import numpy as np
import matplotlib.pyplot as plt

# 生成数据
x = np.arange(0,6,0.1)
y1 = np.sin(x)
y2 = np.cos(x)

# 绘制图形
plt.plot(x,y1,label = "sin")
plt.plot(x,y2,linestyle = "--",label = "cos")# 用虚线绘制
plt.xlabel("x")# x轴标签
plt.ylabel("y")# y轴标签
plt.title('sin & cos')# 添加图标题
plt.legend(loc = 1)# 添加图例
plt.show()
plt.show

# 读取与打印图片
import matplotlib.pyplot as plt
from matplotlib.image import imread
# 读入图像的函数imread,显示图像的函数imshow
img = imread('lena.jpg')# 读入图像(要有路径)
plt.imshow(img)

plt.show()
print(img)# 图像就是一个矩阵

二、感知机

2.1与门感知机

2.1.1线性可分感知机

感知机有多个输入信号与一个输出信号,某一个输入信号会用权重衡量其重要性,然后进行加权求和,并与阈值比较,大于阈值就激活神经元,返回1,小于等于阈值就返回0;

同样地,可以将阈值调整为偏置,这样就直接与0比较大小就行了。

# 与门感知机
def AND(x1,x2):
    w1,w2,theta = 0.5,0.5,0.7
    tmp = x1 * w1 + x2 * w2
    if tmp <= theta:
        return 0
    elif tmp > theta:
        return 1
        
# 利用加偏置的方式写与门感知机
import numpy as np
def AND(x1,x2):
    x = np.array([x1,x2])# 输入
    w = np.array([0.5,0.5])# 权重
    b = -0.7# 偏置
    tmp = np.sum(w * x) + b# 计算信号加权求和加偏置
    if tmp <= 0:
        return 0
    else:
        return 1
                                                                
# 与非门感知机
def NAND(x1,x2):
    x = np.array([x1,x2])# 输入
    w = np.array([-0.5,-0.5])# 权重
    b = 0.7# 偏置
    tmp = np.sum(w * x) + b# 计算信号加权求和加偏置
    if tmp <= 0:
        return 0
    else:
        return 1
        
# 或门感知机
def OR(x1,x2):
    x = np.array =([x1,x2])
    w = np.array = ([0.5,0.5])
    b = 0.3
    tmp = np.sum(w * x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
OR(1,1)

2.1.2线性不可分感知机

就是无法用直线分割的空间,需要用曲线甚至是更复杂的方式才能分割,对于 线性不可分 可以采用叠加层感知机进行分割,如异或门,所谓叠加层,也就是先进行或门,与非门,得到对应的输出,再将这两个输出作为输入,进行与门,就实现了异或门:

# 异或门感知机,叠加层感知机
def XOR(x1,x2):
    s1 = OR(x1,x2)
    s2 = NAND(x1,x2)
    return AND(s1,s2)
    
XOR(0,1)

三、神经网络

3.1激活函数

所谓激活函数,就是在神经元处,将输入信号加权求和并加上偏置得到的值,通过某函数处理一下得到输出值,这个函数就是激活函数,激活函数都是非线性的,因为线性激活函数的处理总能被单层网络以某种方式实现,丧失了叠加层神经网络的优势。

# 激活函数1:阶跃函数
def step_fun(x):
    '''这里的x只能接受实数'''
    if x > 0:
        return 1
    else:
        return 0
        
# 设置成数组的输入的阶跃函数
import numpy as np

def step_fun2(x):
    '''可以接受数组哦'''
    y = x > 0# 非常巧妙地利用了np.array数组的特性,[1.0,-1.0] > 0,返回[True,False]
    return y.astype(np.int)# astype是以将序列中的元素转换为指定的数据类型,如[True,False]转换成[1,0]

import matplotlib.pylab as plt

def step_function(x1):
    return np.array(x1 > 0,dtype = np.int)# 返回一个np.array()数组,并确定元素类型为dtype = np.int

x1 = np.arange(-5.0,5.0,0.1)# 生成范围为-5.0到5.0的步长为0.1的数组
y1 = step_function(x1)
plt.plot(x1,y1)
plt.ylim(-0.1,1.1)# 指定y轴的范围
plt.show()

# 激活函数2:sigmoid函数的实现
def sigmoid(x2):
    return 1 / (1 + np.exp(-x2))# np.exp()对一个数组进行取以e为底的指数数组
x2 = np.arange(-5.0,5.0,0.1)
y2 = sigmoid(x2)
plt.plot(x2,y2)
plt.ylim(-0.1,1.1)
plt.show()

figure = plt.figure()
ax = figure.subplots(1,1)
ax.plot(x1,y1,'r--')
ax.plot(x2,y2)

# 激活函数3:ReLU函数
def relu(x3):
    return np.array(list(map(lambda x: x if x > 0 else 0,x3)))

x3 = np.arange(-5.0,5.0,0.1)
y3 = relu(x3)
plt.plot(x3,y3)

# ReLU函数的实现2
def relu(x3):
    return np.maximum(0,x3)

y3 = relu(x3)
plt.plot(x3,y3)

3.2多维数组的运算

import numpy as np

A = np.array([1,2,3,4])
print(A)
np.ndim(A)# 获取数组的维数,如这个A的维数就是1
A.shape# 获取数组的形状,如这个就是(4,),指的是4*1,如果是二维数组,比如(4,3)指的是4*3的二维数组
A.shape[0]# 返回4

B = np.array([[1,2],[3,4],[5,6]])
print(B)
np.ndim(B)# 2维,行和列
B.shape

X = np.array([[1,2],[3,4]])# 2*2矩阵
Y = np.array([[5,6],[7,8]])# 2*2矩阵
np.dot(X,Y)# 进行矩阵乘法,也称点积,结果还是2*2的矩阵

A = np.array([[1,2],[3,4],[5,6]])# 3*2矩阵
B = np.array([7,8])# 它既可以看成行向量,也可以看作列向量,根据实际情况自动调整的,也就是既可以看为2*1,也可以看出1*2
np.dot(A,B)# 显然这里的B被看作2*1的列向量

# 神经网络的内积
'''X是输入数组,就是(x1,x2),W是权重矩阵,其第m行,就是xm指向后一层n个神经元y1,..,yn的权重顺序数组[w11,w21,w31],如w21指的就是x1->y2的权重,Y是输出数组[y1,y2,y3]'''
X = np.array([1,2])# 1*2
X.shape
W = np.array([[1,3,5],[2,4,6]])# 2*3矩阵
print(W)
W.shape
Y = np.dot(X,W)# 1*3
print(Y)

3.3三层神经网络的实现

3.3.1分层实现

# 神经网络的的第一层信号传递计算
'''X是输入层输入的数组,W1是输入层输入的权重矩阵,A1是在第二层节点处求和得到数组,B1是输入层的偏置数组,Z1是激活函数激活后的数组'''
X = np.array([1.0,0.5])# 1*2
W1 = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])# 2*3
B1 = np.array([0.1,0.2,0.3])# 1*3

print(W1.shape)# (2,3)
print(X.shape)# (2,)
print(B1.shape)# (3,)

A1 = np.dot(X,W1) + B1# 1*3
print(A1)

Z1 = sigmoid(A1)# 1*3
print(Z1)

# 神经网络的的第二层信号传递计算
'''Z1是激活函数激活后的数组,即从第二层输出的数组,W2就是第二层输出数组的权重,A2是在第三层节点处求和得到数组,B2是第二层输入的偏置数组,Z2是A2通过激活函数激活得到的数组'''
W2 = np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
B2 = np.array([0.1,0.2])

print(Z1.shape)
print(W2.shape)
print(B2.shape)

A2 = np.dot(Z1,W2) + B2
Z2 = sigmoid(A2)

# 神经网络输出层的信号传递
'''W3,B3,A3,Y分别是第三层输入的权重,第三层输入的偏置,第四层也就是输出层处的求和,以及输出层的最终输出'''
def identity_fun(x):# 这是恒等函数,作为sigma激活函数,专用于输出层激活,也可以不用定义该函数,只是为了与前面保持一致才定义的
    return x

W3 = np.array([[0.1,0.3],[0.2,0.4]])# 2*2
B3 = np.array([0.1,0.2])# 2*1

A3 = np.dot(Z2,W3) + B3
Y = identity_fun(A3)
print(Y)

3.3.2直接实现

# 三层神经网络的定义
def sigmoid(x2):#定义激活函数sigmoid函数,作为隐层的激活

    return 1 / (1 + np.exp(-x2))# np.exp()对一个数组进行取以e为底的指数数组

def identity_fun(x):# 这是恒等函数,作为sigma激活函数,专用于回归的输出层激活,也可以不用定义该函数,只是为了与前面保持一致才定义的
    return x

def init_network():
    network = {}#创建字典,用来储存三层的权重矩阵和偏置数组
    network['W1'] = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])# 2*3
    network['b1'] = np.array([0.1,0.2,0.3])# 3*1
    network['W2'] = np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
    network['b2'] = np.array([0.1,0.2])
    network['W3'] = np.array([[0.1,0.3],[0.2,0.4]])
    network['b3'] = np.array([0.1,0.2])
    
    return network#返回这个字典

def forward(network,x):#形式参数为(含有各层权重和偏置的字典,输入数组)
    W1,W2,W3 = network['W1'],network['W2'],network['W3']#从字典中按照键获取对应的值
    b1,b2,b3 = network['b1'],network['b2'],network['b3']
    
    a1 = np.dot(x,W1) + b1#一步步进行信号传递的运算,加权求和,加偏置
    z1 = sigmoid(a1)#激活函数激活
    a2 = np.dot(z1,W2) + b2#接着进入下一层网络,以此类推
    z2 = sigmoid(a2)
    a3 = np.dot(z2,W3) + b3
    y = identity_fun(a3)#直到输出层,用恒等函数激活,获取输出数组
    
    return y#返回输出数组

network = init_network()#调用init_network函数获得该字典
x = np.array([1.0,0.5])#生成输入数组
y = forward(network,x)#传入实参,获取返回值输出数组
print(y)

3.4输出层的设计

3.4.1softmax激活函数

softmax函数是针对分类设计的,其各类输出值之和是1,各输出值可以看作出现该种类别的概率,其中概率最大的结果,就认为是输出的类别,又因为softmax函数其实是基于指数函数的,所以不添加这个激活函数,也可以进行分类,因为指数函数是单调递增的,所以输入softmax的值越大,输出的值肯定也越大,直接比输入的值的大小就行了,另外输出层的神经元数量就应该设置成类别的数量。

#softmax函数
a = np.array([0.3,2.9,4.0])
exp_a = np.exp(a)
print(exp_a)
sum_exp_a = np.sum(exp_a)
print(sum_exp_a)
y = exp_a / sum_exp_a
print(y)

#考虑溢出问题的softmax激活函数
a = np.array([1010,1000,990])
np.exp(a) /np.sum(np.exp(a))#因为exp(n),当n很大的时候,会返回一个超出8字节的数字,对象无法保存它,会返回nan

c = np.max(a)
np.exp(a - c) /np.sum(np.exp(a - c))#让a中每个值都减去最大值c,相当于对分子分母同乘以c',不影响结果,但是解决了溢出问题

#定义softmax激活函数
def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c)#解决溢出
    exp_sum_a = np.sum(np.exp(a - c))
    return exp_a / exp_sum_a
a = np.array([0.3,2.9,4.0])
y = softmax(a)
np.sum(y)#显然softmax函数输出的值的和是1,所以各结果的输出值可以称为概率

3.5手写数字识别

采用前向传播神经网络,所谓前向传播,就是将学习到的参数,用来实现神经网络的推理。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会抓鼠鼠的阿猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值