深度学习的学习记录(一)

目录

任务

初步了解深度学习及神经网络。

豆豆实验一

两个模型(莫克罗-彼特氏神经模型和罗森布拉特感知器模型)

jupyter notebook

Numpy

动手学上的部分代码

​梯度

第二次豆豆课(方差代价函数)

第二次豆豆代码编程(梯度下降)

 总结的英语单词


任务

  1. 任务:看完深度1.学习的简介和11.附录,阅读和了解关于深度学习的文章,视频,讲座。对深度学习有清晰的认识。.
  2. 看完2,打算熟悉熟悉python和深度学习再准备看沐神的书和视频。看群里大佬讨论问题,并尝试给比我还小白的小白解决问题。
  3. 回顾一下两个模型。整理所用软件常见和不认识的英文单词
  4. 买书,周志华机器学习的西瓜书和南瓜书,等到学到后期看情况买机器学习的花书回头看。

jupyter notebook的学习网站

机器学习新手必看:Jupyter Notebook入门指南_CSDN人工智能头条-CSDN博客

初步了解深度学习及神经网络。

一个图像,判断图里有无猫🐱,400像素的图像有50多万的数值,这些数值有无用数值,也有有用数值。成千上万的有用数值组成猫的特征(鼻子,毛...)进行判断。我们人判断一个东西是不是猫也是需要通过一些外部数据,耳朵听到的叫声,眼睛看到的物体,大脑稍微处理一下即可判断。

对于机器来说,肯定也是需要外部的数据的,机器没有脑子,对于如何处理这些数据就成了主要思考的问题。通过b站的视频,比如生活中深海中的一生物小蓝,它的食物是一种类似豆子的有毒食物豆豆。在两种生物几千年的反复博弈下,被吃的一方豆豆会随着自己生长毒性也随之增加,而捕食者小兰也进化出能分辨出豆豆大小的器官。那么问题来了,小兰是如何根据豆豆的大小分辨它到底有多毒呢?没错,他还缺少一思考器官,也就是我们所说的脑子。但我们又如何描述思考(认知)呢?认知之前就是一无所知,这种情况下认知事物的唯一方法就是依靠直觉。那我们应该如何描述直觉呢?很明显——函数。气温对人心情的影响。用函数表达对GDP的认知。一个小狗眼睛的大小和他的可爱程度关系,也可以用一函数画出函数图像来展示。这正需要我们用人工智能,找到恰当的函数来描述它。如此这般,把智能体对世界的认知过程,看在是在脑中不断形成的各种函数,也就很有道理了。如果豆豆的毒性还与颜色有关,则函数为y=w1x1+w2x2(二元函数)                                                                                              

                                                                                                                                                                                                                                      左为轴突,右为树突

  

树突一般有很多输入端,如果只有一个输入,也就是一元函数y=wx;如果有两个输入端就是上面提的二元函数y=w1x1+w2x2(x1代表豆豆大小,x2代表豆豆颜色)等等;

而对于参数w,它实际上起着控制树突上输入信号的作用(话句话说控制着不同输入对输出的影响),也称为权值。因为我们在判断一个东西时,不同因素对结果的重要性都不太一样。也正因为如此,我们会发现McCulloch-Pitts模型选择用一次函数,而不是其他的函数来模仿神经元是很自然的一件事。

树突的输入x ,被权值参数扩大或者是缩小,然后输出,简单且有效。

w取不同的值,斜率不一样,除非是恰当的斜率,否则小蓝就会吃到毒性与自己不匹配的豆豆。于是现所面临的问题是,这个一元一次直觉函数中的参数w设置为多少?小蓝才能很好的进行预测。

权重(斜率)是0.1时,小蓝会错估豆豆的毒性。身为人类的我们肯定知道只需要把权重调节到适当即可,但是机器是不知道如何调节权重的。未免太不智能。在McCulloch-Pitts模型上提出Rosenblatt感知器模型,他让神经元有了能自主调节权重的能力。

先考虑只有一个输入的情况,然后会输出一个结果,用标准答案剪掉这个结果,这意味着预测和标准之间的误差,自然是根据误差去调整参数。让W加上这个误差作为新的W ,这样就做到了,预测结果过小时,误差为正数,W加上误差之后向大调整。下次预测时结果就提升了。反之,预测过大,误差是负数,W向小调整(预测的大了,你肯定想让他小啊)。这就是Rosenblatt感知器的学习过程,通过误差修正参数

当x为正数,预测过大(即函数图像在标准之上),误差为负数,W+误差  *  x   =新W  ,W减小。即斜率减少,更加靠近准确值      

                                                                                                           负            正

                    预测过小(即函数图像在标准之下),误差为正数,W+误差 * x = 新W。W增加。即斜率增加,更加靠近准确值

                                                                                                            正              正               

    当x为负数,预测过大(函数图像在标准之上),误差为负数,W+误差 * x = 新W,W增大  。斜率增大,更加靠近准确值           

                                                                                                             负             负                 

                      预测过小(即函数图像在标准之下)  误差为正数,W+误差 * x = 新W,W减小,斜率减少,更加靠近准确值

                                                                                                              正             负                 

安装miniconda,搜教程配置环境,已成功配置完环境,配置环境感觉蛮麻烦的,要下很多东西,看别人说不翻墙的话,还是用国内的镜像快一点,不过我自己没有翻墙也没用镜像下,感觉也是蛮快的,地区在北方的话用清华的镜像建议。看一看Jupyter Notebook,简单了解下,因为之前接触Java语言蛮多,所以用eclipse蛮多,其他软件和web程序几乎没怎么用过,但是学好深度学习,tensflow的前提肯定要用python,所以以后也要开始补python。

豆豆实验一

dataset.py

import numpy as np

def get_beans(counts):
	xs = np.random.rand(counts)
	xs = np.sort(xs)
	ys = [1.2*x+np.random.rand()/10 for x in xs]
	return xs,ys

看pycharm的博客,了解这个编辑器 ,然后做豆豆的编程实验

import dataset   #导入生成豆豆的数据
from matplotlib import pyplot as plt
#获取100个豆豆的大小毒性   xs豆豆大小,ys豆豆毒性
xs,ys=dataset.get_beans(100)   #可以有两个返回值,生成100个豆豆
print(xs)
print(ys)

plt.title("Sixe-Toxicity Function",fontsize=15)     #设置图表的标题

plt.xlabel("豆豆大小")
plt.ylabel("毒性")
plt.scatter(xs,ys)   #毒性大小散点图(scatter函数)plot函数是画线图

#罗森布拉特感知器
# 预测函数 y=0.5*x
w=0.5    #对于输入的一个豆豆大小  进行固定值的预测(初始斜率)

#拟定学习100次
for m in range(100):            #多调整几次,由于调整一次未必能有好的收敛性
    for i in range(100):        #用range函数进行for循环
        x = xs[i]               #第i个豆豆的大小数据
        y = ys[i]
        y_pre = w * x           #第i个豆豆的毒性数据
        e = y - y_pre           #用标准答案-预测毒性=误差
        alpha = 0.05            #学习率,是为了防止大幅震荡
        w = w + alpha * e * x   #调整斜率(斜率=斜率+误差*豆豆大小*学习率)

y_pre=w*xs    #拿第一个豆豆的数据预测毒性值,第二个...不需搞个while,只需用nupm的广播特性
print(y_pre)
plt.plot(xs,y_pre) #plot函数画线
#让输出的图表可以有中文
plt.rcParams["font.sans-serif"] = "SimHei"
plt.show()#相当于图表的刷新

   

  

看群里的大佬有用jupyter notebook ,正好学沐神的课,也都是用jupyter notebook 看看能不能运行出来我的代码。

不过需要把print函数删掉,不然出很多豆豆的数据.看着不美观

两个模型(莫克罗-彼特氏神经模型罗森布拉特感知器模型

最后回忆回忆两个模型

   

jupyter notebook

  先进入环境  

 activate gluon

再在终端输入

jupyter notebook

会在本地浏览器的localhost:8888打开,然后在此web应用程序开始实时敲代码,不能将终端关掉。如果同时打开多个jupyter notebook的话,会出现8888端口占用的情况。图为借鉴,因为之前用eclipse敲代码会出现8080端口占用,感觉很麻烦,由于不知道会出现什么情况,先码着,过几天去网吧安一个andonda把不确定想测试的东西统一玩一下。不过按别的博客来看,端口占用直接复制新的url,会重新分配一个端口,从8889以此类推。

用acivate激活环境

进入主页面

上图是看别的博主的博客所截图,cd和ls的一些指令让我想起了学linux,不过现在也快忘光了。于是我在jupyter notebook的终端输入了上面的指令,显示的是家目录下的文件。

Numpy

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库

动手学上的部分代码

在jupyter notebook 里new一个python3 ,在markdown里输入标题,#内容,#和内容之间要加空格

运行 from mxnet import nd报错 ,只需要在终端pip install mxnet ,然后import就行了。

from mxnet import nd
x=nd.arange(12)
x

from mxnet import nd
x=nd.arange(12)
x
x.shape
x.size

跟着书上的代码敲,都敲了一边,于是想把所有代码都放在一个单元里,看能否运行,结果是只能运行单元里最后一行的代码.

nd.zeros((2,3,4))想起来前几天学matlab的知识了

nd.zeros((2,3,4))这里的2是创建两个矩阵,3是3行,4是4列

如果你要创造某个东西,就得用nd.啥啥啥(一般要有) ,矩阵的乘法要用nd.dot           向量,矩阵,矩阵的乘法

from mxnet import nd
x=nd.arange(12)
x

 nd()里的shape要加=                           如果看x的属性,只需x.啥啥啥

                                                                                                       

x.reshape(2,3,4)

           

报错一般看最后一行,根据最后一行找错误。12个元素没法分到两个3行4列的矩阵,所以报错

from mxnet import nd
x=nd.arange(12)
x.reshape(2,2,3)

   

自定义一个矩阵一对括号里面两个中括号

不同行不同列的矩阵相加可能会触发广播机制,由于A和B分别是3行1列和1行2列的矩阵,如果要计算A + B,那么A中第一列的3个元素被广播(复制)到了第二列,而B中第一行的2个元素被广播(复制)到了第二行和第三行。如此,就可以对2个3行2列的矩阵按元素相加。

预期竟然不一样,本来我觉着是可行的。我用的是一个2行3列,和3行4列.,在进行广播测试时,发现了一个别的问题,现记录下来,不能把两个矩阵的代码放在单元格的同一行,否则会出现语法错误。

from mxnet import nd
A=nd.array([[1,5,9],[7,5,3]])  B=nd.array([[7,4,1,8],[9,6,3,8],[7,4,9,1]])
A,B

from mxnet import nd
A=nd.array([[1,5,9],[7,5,3]])  
B=nd.array([[7,4,1,8],[9,6,3,8],[7,4,9,1]])
A,B

A+B

显示这种形状的不能广播

不能广播,emmmm,是因为前一个矩阵的行列数都比后一个矩阵的行列数都小吗?我尝试一下,二行三列和二行四列,也是不可以;那我试试二行三列和一行四列,为啥也不行呢?是不是我哪里搞错了……回去看看为啥他的列子能行。我的代码错了可能。我是直接定义的矩阵进行矩阵相加。我试试按沐神的代码。也是不能广播的,仔细看了下沐神的书,上面说的是可能会发生广播机制。并不是一定会广播。

                                                                  

一直下意识以为是从1开始的。

梯度

from mxnet import autograd, nd

对函数 y=2x^⊤x 求关于列向量 x 的梯度。我们先创建变量x,并赋初值。


x = nd.arange(4).reshape((4, 1))
x

                 

   

x.attach_grad() #为了求有关变量x的梯度,我们需要先调用attach_grad函数来申请存储梯度所需要的内存。
with autograd.record():    #调用record函数来要求MXNet记录与求梯度有关的计算。
 y = 2 * nd.dot(x.T, x)   #y的前面要加空格,否则会出现缩进错误
y.backward()              #求梯度
assert (x.grad - 4 * x).norm().asscalar() == 0   #x梯度减4x的范数标量如果为0
x.grad        

就是拿x的梯度减去4x,为0,用来验证一下求出来的梯度是正确的。

def f(a):
    b = a * 2
    while b.norm().asscalar() < 1000:
        b = b * 2
    if b.sum().asscalar() > 0:  #如果所有b求和的标量大于0
        c = b
    else:
        c = 100 * b
    return c

a = nd.random.normal(shape=1)  #让a=随机的一个大小形状为1的量    创建一个元素的NDArray
a.attach_grad()          #分配内存
with autograd.record():       #记录
    c = f(a)
c.backward()              #求梯度

a.grad == c / a

第二次豆豆课(方差代价函数)

从Rosenblatt感知器身上可以看出,参数的自适应调整是人工神经元的精髓

为什么就该是这样?

首先,我们应该如何评估误差?第一反应是差值。但是这种评估误差的方法并不好。

因为如果只有两个数据的话,这样算的误差为0,但是从图像来看,显然并不是这样的。这就是用差值评估误差的问题。插值有正负,所以会发生相互抵消作用。然后会想到用差值的绝对值。这是一种方法,用绝对值处理的误差叫“绝对差”,但绝对值在数学处理和编码处理上都不方便。然后提出更方便处理误差的方法,就是把差值取平方,正负号也就消失了。这种误差也就是所谓的“平方误差”。很明显,我们对一批豆豆预测的结果和标准答案的之间的平方误差越小,说明偏离事实越小,海底生物小蓝的思考也就越接近真相。

我们知道实际上是参数w决定了预测函数y=wx的样子(斜率不同,图像不同嘛),换句话说,每次w去不同的值,产生的误差也会不同。所以如果,我们把误差和参数w之间的关系画出来是这样的曲线,很像一开口向上的一个一元二次函数。所以要怎么证明它是一个开口向上的一个一元二次函数?

研究一组豆豆太麻烦了,不如我们先研究一个豆豆,大小是0.4,毒性是0.68这就是一个标准的一元二次函数,w是自变量,e是因变量。

这只是一个豆豆,对于一组豆豆来说,其实结果也是这样。我们可以找一个大小为x0,毒性为y0的豆豆,对于大小为x1,毒性为y1的豆豆

也就是说对于任意一个大小和毒性的豆豆,它的预测误差和参数w的关系都是一个开口向上的抛物线

 所以在一组豆豆上计算出的整体误差,还是不是一个开口向上的抛物线呢?它们的整体误差就是把单个豆豆的预测误差加起来再求平均,我们从第0个豆豆一直加到第m个豆豆,把含有二次项的,一次项,零次项的稍微整理一下

  也就是 

看得出误差e和参数w的关系仍然是一个标准的一元二次函数,它描述了取不同值时,海底生物小蓝对于一组豆豆预测的整体误差,这个公式又臭又长,而数学讲究的是简洁优美,而每个豆豆的误差形式又都是一样的,所以我们一般用求和符号表示整体误差。当然这个时候取得是平方误差的平均值,所以我们也称e为均方误差。面对多个数据,我们只需把单个误差求出来,再全部加在一起平均一下,这就是预测函数在整体样本上的误差,而上面说的单个豆豆只是特例。

当我们知道不同的w取值对误差的影响后,接下来的事就简单了,我们让机器自己去寻找这个开口向上的抛物线的最低点,此处也恰是误差的最小点

我们说函数是我们对事物认知的数学描述,一般情况下函数(认知)的形成过程,都是由某个问题的额专家通过多年的经验总结出来的,比如牛顿研究物体受力多年总结出加速度和受力的函数关系。但是世界是复杂的,很多非理想的环境下我们一点点研究和总结是不现实的。比如正常来说,一枚质地均匀的硬币,抛掷出去,正反两面的概率应该都是1/2,但是在硬币的一侧,灌入较重的东西,其概率也势必会发生变化。当然我们可以用精密的仪器和技术来研究硬币的材质,受力模型等等,得到一个极其复杂的概率函数,但是更“简单”的方法是统计,也就是说我们不断地抛掷这枚硬币,并记录朝向,当抛掷的次数足够大时,我们可以看统计的数据从而达到概率。这也就是我们常说的事物出现的频率收敛于它的概率

我们在设计小蓝的大脑时,其实也是在干抛掷一枚不确定的硬币这件事,一开始我们猜想一个w,然后统计出大量的数据(豆豆的大小和毒性),去评估我们的这个w 到底合不合适。这就是数理统计学里面的重要的一个分支-回归分析,而我们评估的标准是均方误差。,并试图让它最小,也就是回归分析中的最小二乘法,此时此刻,我们把函数看作处理问题的机器,那么事情从原先的向机器输入数据,得到结果变成为用很多观察到的数据去评估这个函数机器到底是否在行,原先的自变量x和因变量y变成了从环境中观测到的大量已知数。我们把w作为自变量,误差e作为因变量,也就形成了一个新的函数——代价函数(cost function),当参数w取不同值的时候,对环境的问题数据预测时产生不同的误差e,而利用代价函数的最低点的w的值,把它放回预测函数中,这时候预测函数也就很好的完成了对数据的拟合

如果一开始的w是0.1,没有达到最低点,究竟如何让机器自己去把w向最低点挪动呢?-b/2a就可以。

先看样本只有一个豆豆的简单情况。代入计算得最低点的w值是y0/x0

再来看样本有多个豆豆的一般情况,     =

代入计算

这种一次性求解出让误差最小的w取值的方法,也就是所谓的“正规方程”。只不过我们没有说矩阵和向量,只是采用单个数值,当我们把正规方程中的矩阵和向量都退化成单个数值

这种方法当样本数量比较小的时候,其实这很合适。但是机器学习一般需要海量的数据,这种一步到位的方式,就意味着巨大的计算量和存储量。

比如我们有100万条样本数据,每个数据用一个单精度浮点型数表示,那么在正规方程中,比如分母部分,就要运行100万次乘法和加法的浮点运算,而实际上输入x在实际应用中往往不会是只有一个特征数值,更一般的时候是一个多维度的向量,比如1000维度,那么这个运算的次数就是10亿次,而在现在神经网路中为了加快运算速度,一般都会采用并行计算的方式,也就是说一次性把它们计算出来。据我自己的个人了解,电脑的运算都是大多是靠显卡来提供算力,这得多烧显卡啊.......

第二次豆豆代码编程(梯度下降)

这次我直接用的是jupyter notebook,感觉jupyter notebook的简洁让我感觉很舒服。

dataset.py

import numpy as np

def get_beans(counts):
	xs = np.random.rand(counts)
	xs = np.sort(xs)
	ys = [1.2*x+np.random.rand()/10 for x in xs]
	return xs,ys

import dataset   #导入生成豆豆的数据
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
import dataset   #导入生成豆豆的数据
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

#获取100个豆豆的大小毒性   xs豆豆大小,ys豆豆毒性
xs,ys=dataset.get_beans(100)   #可以有两个返回值,生成100个豆豆

 
plt.title("Sixe-Toxicity Function",fontsize=15)     #设置图表的标题
plt.xlabel("豆豆大小")
plt.ylabel("毒性")
plt.scatter(xs,ys)   #毒性大小散点图(scatter函数)plot函数是画线图
w=0.1

y_pre=w*xs    #拿第一个豆豆的数据预测毒性值,第二个...不需搞个while,只需用nupm的广播特性
plt.plot(xs,y_pre) #plot函数画线
#让输出的图表可以有中文
plt.rcParams["font.sans-serif"] = "SimHei"
plt.show()#相当于图表的刷新

xs,ys=dataset.get_beans(100)
plt.title("Sixe-Toxicity Function",fontsize=15)     #设置图表的标题
 
es=(ys-y_pre)**2 #a**b表示的是a的b次方
sum_e=np.sum(es)
sum_e=(1/100)*sum_e
print(sum_e)
ws=np.arange(0,3,0.1)  #第一个参数0是数组的起始值,第二个参数3是数组的结束值,第三个参数0.1是每次递进的大小
es=[]

#用for循环取出不同的w代入预测函数计算
for w in ws:
    y_pre=w*xs
    e=(1/100)*np.sum((ys-y_pre)**2)  #100个误差加起来再除以100求平均值
    print("w:"+str(w)+"e:"+str(e)) #打印的时候w和e都是属于浮点型的数字,所以我们需要用str函数先把它转换成字符串,不然用加号拼接会出现错误
    es.append(e)   #在每次w去不同的值时把它放进这个数组中。
    
plt.title("代价函数图像(cost Function)",fontsize=12)     #设置图表的标题
plt.xlabel("参数w")
plt.ylabel("均方误差e")
plt.plot(ws,es)
plt.rcParams["font.sans-serif"] = "SimHei" #让输出的图表里可以有中文
plt.show()

w_min=np.sum(xs*ys)/np.sum(xs*xs)
print("e最小值w:"+str(w_min))


y_pre=w_min*xs
plt.title("豆子毒性和大小图像(Size-Toxicity Function)",fontsize=15)     
 
plt.xlabel("豆豆大小")
plt.ylabel("毒性")
plt.scatter(xs,ys)

plt.plot(xs,y_pre)
plt.show()

总的截图

 总结的英语单词

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值