0118-深度学习基础及一些代码实例
这里写目录标题
- 深度学习入门
- 1.深度学习基础
- 1.1 深度学习与传统神经网络的区别
- 1.2 深度学习合适的目标函数
- 1.3 Softmax层
- 1.3.1Softmax层体现和作用?
- 2 Softmax层的实现:
- 1.4 激活函数(Relu)
- 1.4.1 为什么不用tanh和Sigmoid(梯度消失的直观解释)
- 1.4.2 Relu激活函数
- 1.4.3 采用ReLU激活函数后
- 1.5 学习步长
- 1.6 关于SGD(随机梯度下降算法)的问题讨论(Deep Learning 最优化方法)
- 1.6.1 momentum(动量梯度下降法)
- 1.6.2 Nesterov momentum(牛顿动量)
- [1.6.3Adagrad(Adaptive Gradient)](https://blog.csdn.net/weixin_43378396/article/details/90743268?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164251153116780255215326%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164251153116780255215326&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-90743268.first_rank_v2_pc_rank_v29&utm_term=Adagrad&spm=1018.2226.3001.4187)
- 1.6.4 RMSprop
- 1.6.5 Adam( adaptive moment estimation,自适应矩估计)
- 1.6.6 各种梯度下降算法的比较
- 关于算法
- 总结几节课出现的代码
- Grabcut的opencv实现
- 人脸检测的Opencv实现(harr)
- 模板匹配式的人脸识别
- Haar小波人脸识别
- 有关简单的神经网络
- tf实现感知器
- tf实现简单的三层网络
- DIY一个简单的BP算例(双层网络)
- 简单的CNN例子
深度学习入门
1.深度学习基础
1.1 深度学习与传统神经网络的区别
1.2 深度学习合适的目标函数
我们在传统神经网络里已经得到一种目标函数就是均方误差:
但是在深度学习里面最常见的目标函数是交叉熵,如下图所示:
从上图可以的看到交叉熵收敛的比均方差快的多!!可以想象为交叉熵目标函数的最优值搜索空间的“地形”更“陡”,更有利于快速的找到最优值,如下图所示。
注意线性回归的时候均方差比较好用,但是作分类问题的时候交叉熵比较好用,因为交叉熵涉及到了概率的观念。
有关交叉熵的介绍
1.3 Softmax层
一个介绍Softmax的帖子
1.3.1Softmax层体现和作用?
在做分类预测的时候,经常会选择在神经网络的最后一层的输出结果上,加一个softmax层,来对输出结果进行分类。
如下图示在output layer后多出来的一个黑色的layer,就是用于分类的softmax层。最后紫色的new output层就是经过softmax层后,转换成概率的新输出层。
从这个图上可以看出来,softmax层只是对神经网络的输出结果进行了一次换算,将输出结果用概率的形式表现出来,而且它还起到了突出“最大值”的作用。
2 Softmax层的实现:
softmax层对L2层传来的数值进行一个换算,换算公式如下:
如下图我们最终会得到(3,1,-3)对一的概率是(0.88,0.12,0)且后者和为1:
1.4 激活函数(Relu)
1.4.1 为什么不用tanh和Sigmoid(梯度消失的直观解释)
所以所谓的梯度消失和梯度爆炸就是:因为网络太深,网络权值更新不稳定造成的,本质上是因为梯度反向传播中的连乘效应。
而对于更普遍的梯度消失问题,都是考虑用ReLU激活函数取代sigmoid激活函数。
1.4.2 Relu激活函数
之前已经介绍过了Relu函数和其导数如下
1.4.3 采用ReLU激活函数后
这也避免了调整各层权重时的“梯度消失”的问题。
1.5 学习步长
学习步长的设置是个难题:若学习步长过大,则目标函数可能不降低;但若学习步长过小,则训练过程可能非常缓慢。
解决方法:训练几轮后就按一些因素调整学习步长。
介绍一种修改方法:
根据学习轮次t来对学习步长进行调整
1.6 关于SGD(随机梯度下降算法)的问题讨论(Deep Learning 最优化方法)
(1)learning rate不易确定,如果选择的太小,收敛速度会很慢;如果太大,loss function 就会在极小值处不停地震荡甚至偏离。
(2)每个参数的 learning rate 都是相同的,如果数据是稀疏的,则希望对出现频率低的特征进行大一点的更新。
(3)深层神经网络之所以比较难训练,并不是因为容易进入局部最小,而是因为学习过程容易陷入到马鞍面中,在这种区域中,所有方向的梯度值都几乎是 0。
1.6.1 momentum(动量梯度下降法)
针对极小值处不停地震荡甚至偏离的问题引入动量的概念:
区别: SGD每次都会在当前位置上沿着负梯度方向更新(下降,沿着正梯度则为上升),并不考虑之前的方向梯度大小等等。而动量(moment)为了表示动量,引入了一个新的变量v。v是之前的梯度的累加,但每回合都有一定的衰减。
一个直观的解释动量梯度下降方法是:若当前的梯度方向与累积的历史梯度方向一致,则当前的梯度会被加强,从而这一步下降的幅度更大。若当前的梯度方向与累积的梯度方向不一致,则会减弱当前下降的梯度幅度。即前后梯度方向一致时,能够加速学习;前后梯度方向不一致时,能够抑制震荡。
实现方法:
1.6.2 Nesterov momentum(牛顿动量)
Nesterov Momentum是对Momentum的改进,可以理解为nesterov动量在标准动量方法中添加了一个校正因子。用一张图来形象的对比下momentum和nesterov momentum的区别:
实现方法:
这个算法的运行速度比momentum要慢两倍,因此在实际实现过程中几乎没人直接用这个算法,而都是采用了变形版本。
1.6.3Adagrad(Adaptive Gradient)
1.6.4 RMSprop
RMSprop是一种改进的Adagrad,通过引入一个衰减系数,让r每回合都衰减一定比例,从而使得梯度不会一直累加。这种方法很好的解决了Adagrad过早结束的问题,适合处理非平稳目标,对于RNN效果很好。
1.6.5 Adam( adaptive moment estimation,自适应矩估计)
Adam本质上是带有动量项的RMSprop,它利用梯度的一阶矩(momentum)估计和二阶矩(Adagrad,RMSprop)估计动态调整每个参数的学习率。
一个有关动量,rmsprop,adam的帖子,内容很完整
1.6.6 各种梯度下降算法的比较
如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。
RMSprop, Adadelta, Adam 在很多情况下的效果是相似的。通常,Adam 是最好的选择。
很多论文里都会用 SGD,没有 momentum 等。SGD 虽然也能达到极小值,但是比其它算法用的时间长,而且可能会被困在鞍点。SGD相对稳定——据说老司机都是开手动挡的。
关于算法
(1)首先,各大算法孰优孰劣并无定论。如果是刚入门,优先考虑 SGD+Nesterov Momentum或者Adam.
(2)选择熟悉的算法——这样可以更加熟练地利用经验进行调参。
(3)充分了解数据——如果模型是非常稀疏的,那么优先考虑自适应学习率的算法。
(4)根据需求来选择——在模型设计实验过程中,要快速验证新模型的效果,可以先用Adam;在模型上线或者结果发布前,可以用精调的SGD进行模型的极致优化。
(5) 先用小数据集进行实验。有论文研究指出,随机梯度下降算法的收敛速度和数据集的大小的关系不大。因此可以先用一个具有代表性的小数据集进行实验。
(6)考虑不同算法的组合。先用Adam进行快速下降,而后再换到SGD进行充分的调优。
(7) 数据集一定要充分的打散(shuffle)。这样在使用自适应学习率算法的时候,可以避免某些特征集中出现,而导致的有时学习过度、有时学习不足,使得下降方向出现偏差的问题。
(8)训练过程中持续监控训练数据和验证数据上的目标函数值以及精度或者AUC等指标的变化情况。对训练数据的监控是要保证模型进行了充分的训练;对验证数据的监控是为了避免出现过拟合。
(9)制定一个合适的学习率衰减策略。可以使用定期衰减策略,比如每过多少个epoch就衰减一次;或者利用精度或者AUC等性能指标来监控。
总结几节课出现的代码
Grabcut的opencv实现
几个关键函数的解读:
(1)
grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None)
img: 输入图像,必须是8位3通道图像,在处理过程中不会被修改
mask: 掩码图像,用来确定哪些区域是背景,前景,可能是背景,可能是前景等。GCD_BGD (=0), 背景; GCD_FGD (=1),前景;GCD_PR_BGD (=2),可能是背景;GCD_PR_FGD(=3),可能是前景。
rect: 包含前景的矩形,格式为(x, y, w, h)
bdgModel,fgdModel: 算法内部使用的数组,只需要创建两个大小为(1,65),数据类型为np.float64的数组
iterCount: 算法迭代的次数
mode: 用来指示grabCut函数进行什么操作:
cv.GC_INIT_WITH_RECT (=0),用矩形窗初始化GrabCut;
cv.GC_INIT_WITH_MASK (=1),用掩码图像初始化GrabCut。
(2)在图像上绘制矩形和圆形区域区域
cv.rectangle(img, (ix, iy), (x, y), BLUE, 2)
cv.circle(img, (x, y), thickness, value['color'], -1)
(3)创建鼠标响应事件
窗体对象是’input‘,响应函数是onmouse
cv.setMouseCallback('input', onmouse) # 创建鼠标响应事件
实现源码:
import numpy as np
import cv2 as cvBLUE = [255, 0, 0] # rectangle color
RED = [0, 0, 255] # PR BG
GREEN = [0, 255, 0] # PR FG
BLACK = [0, 0, 0] # sure BG
WHITE = [255, 255, 255] # sure FGDRAW_BG = {'color': BLACK, 'val': 0}
DRAW_FG = {'color': WHITE, 'val': 1}
DRAW_PR_FG = {'color': GREEN, 'val': 3}
DRAW_PR_BG = {'color': RED, 'val': 2}# setting up flags
rect = (0, 0, 1, 1)
drawing = False # flag for drawing curves
rectangle = False # flag for drawing rect
rect_over = False # flag to check if rect drawn
rect_or_mask = 100 # flag for selecting rect or mask mode
value = DRAW_FG # drawing initialized to FG
thickness = 3 # brush thicknessdef onmouse(event, x, y, flags, param):global img, img2, drawing, value, mask, rectangle, rect, rect_or_mask, ix, iy, rect_over# 以下为绘制矩形的整个阶段:鼠标右键按下,鼠标移动,鼠标右键松开if event == cv.EVENT_RBUTTONDOWN:rectangle = Trueix, iy = x, yelif event == cv.EVENT_MOUSEMOVE:if rectangle is True:img = img2.copy()cv.rectangle(img, (ix, iy), (x, y), BLUE, 2)rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))rect_or_mask = 0elif event == cv.EVENT_RBUTTONUP:rectangle = Falserect_over = Truecv.rectangle(img, (ix, iy), (x, y), BLUE, 2)rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))rect_or_mask = 0print(" 如确定当前图无需再改按下'n' \n")# 绘制细节if event == cv.EVENT_LBUTTONDOWN:if rect_over is False:print("矩形区域还没有绘制!! \n")else:drawing = Truecv.circle(img, (x, y), thickness, value['color'], -1)cv.circle(mask, (x, y), thickness, value['val'], -1)elif event == cv.EVENT_MOUSEMOVE:if drawing is True:cv.circle(img, (x, y), thickness, value['color'], -1)cv.circle(mask, (x, y), thickness, value['val'], -1)elif event == cv.EVENT_LBUTTONUP:if drawing is True:drawing = Falsecv.circle(img, (x, y), thickness, value['color'], -1)cv.circle(mask, (x, y), thickness, value['val'], -1)if __name__ == '__main__':filename = './image/lenna.jpg'img = cv.imread(filename)img2 = img.copy() # a copy of original imagemask = np.zeros(img.shape[:2], dtype=np.uint8) # mask initialized to PR_BGoutput = np.zeros(img.shape, np.uint8) # output image to be shown# 定义输入输出窗口cv.namedWindow('output')cv.namedWindow('input')# 创建鼠标响应事件,窗体对象是’input‘,响应函数是onmousecv.setMouseCallback('input', onmouse) # 创建鼠标响应事件# 移动窗体位置cv.moveWindow('input', img.shape[1] + 100, 90)print(" 说明: \n")print(" 按住鼠标右键绘制矩形区域,确定前景包含在内的矩形区域 \n")while True:cv.imshow('output', output)cv.imshow('input', img)k = cv.waitKey(1)# key bindingsif k == 27: # esc to exitbreakelif k == ord('0'): # 背景淹模图像绘制print(" 左键标记背景细节区域 \n")value = DRAW_BGelif k == ord('1'): # FG drawingprint(" 左键标记前景细节区域 \n")value = DRAW_FGelif k == ord('2'): # 可能背景绘制print(" 左键标记可能背景细节区域 \n")value = DRAW_PR_BGelif k == ord('3'): # 可能前景绘制print(" 左键标可能前景细节区域 \n")value = DRAW_PR_FGelif k == ord('s'): # 保存图片bar = np.zeros((img.shape[0], 5, 3), np.uint8)res = np.hstack((img2, bar, img, bar, output))cv.imwrite('grabcut_output.png', res)print(" Result saved as image \n")elif k == ord('r'): # reset everythingprint("流程重新开始\n")rect = (0, 0, 1, 1)drawing = Falserectangle = Falserect_or_mask = 100rect_over = Falsevalue = DRAW_FGimg = img2.copy()mask = np.zeros(img.shape[:2], dtype=np.uint8) # mask initialized to PR_BGoutput = np.zeros(img.shape, np.uint8) # output image to be shownelif k == ord('n'):print(""" 为了对细节进行再绘制, 按下0-3后开始标记前景或者背景(0-背景,1-前景,2-可能背景,3-可能前景),确定后按下’n‘ \n""")# 第一次用矩形区域计算,之后用掩码图像计算更新if rect_or_mask == 0: # grabcut with rectbgdmodel = np.zeros((1, 65), np.float64)fgdmodel = np.zeros((1, 65), np.float64)cv.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv.GC_INIT_WITH_RECT)rect_or_mask = 1elif rect_or_mask == 1: # grabcut with maskbgdmodel = np.zeros((1, 65), np.float64)fgdmodel = np.zeros((1, 65), np.float64)cv.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv.GC_INIT_WITH_MASK)mask2 = np.where((mask == 1) + (mask == 3), 255, 0).astype('uint8')output = cv.bitwise_and(img2, img2, mask=mask2)cv.destroyAllWindows()
人脸检测的Opencv实现(harr)
模板匹配式的人脸识别
#!usr/bin/env python
# -*- coding:utf-8 _*-
import cv2
import numpy as np# 读取图片,彩色模式
img_color = cv2.imread('faces.jpg', cv2.IMREAD_COLOR)
# 读取图片,灰度模式
img_gray = cv2.imread('faces.jpg', cv2.IMREAD_GRAYSCALE)
# 读取人脸模板图片,灰度模式
template = cv2.imread('face_template1.jpg', cv2.IMREAD_GRAYSCALE)
# 获取模板尺寸
w, h = template.shape[::-1]
# 模板匹配方法数组
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF','cv2.TM_SQDIFF_NORMED']
# 遍历匹配方法
for meth in methods:# 拷贝图片img_color2 = img_color.copy()img_gray2 = img_gray.copy()# 把字符串转换成代码method = eval(meth)# 模板匹配res = cv2.matchTemplate(img_gray2, template, method)# 获取匹配结果的最大、最小值,及其位置min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)# TM_SQDIFF 和 TM_SQDIFF_NORMED匹配方法:值越小,越相似if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:# 取最小值位置,作为矩形框左上角位置top_left = min_locelse:# 取最大值位置,作为矩形框左上角位置top_left = max_loc# 根据模板尺寸计算出:矩形框右下角位置bottom_right = (top_left[0] + w, top_left[1] + h)# 画矩形框cv2.rectangle(img_color2, top_left, bottom_right, 255, 2)# 显示画好矩形框的图片cv2.namedWindow(meth, cv2.WINDOW_AUTOSIZE)cv2.imshow(meth, img_color2)# 等待退出键
cv2.waitKey(27)# 销毁显示窗口
cv2.destroyAllWindows()
Haar小波人脸识别
要建立分类器:face_cascade = cv2.CascadeClassifier
然后调用face_cascade.detectMultiScale进行识别
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: hamme
@file: 02_FaceDetection_Haar.py
@time: 2022/01/17
@desc:
"""
import numpy as np
import cv2# 实例化人脸分类器
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
# 实例化眼睛分类器
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
# 读取测试图片
img = cv2.imread('faces2.jpg', cv2.IMREAD_COLOR)
# 将原彩色图转换成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 开始在灰度图上检测人脸,输出是人脸区域的外接矩形框
faces = face_cascade.detectMultiScale(gray, 1.2, 8, cv2.CASCADE_SCALE_IMAGE)
# 遍历人脸检测结果
for (x, y, w, h) in faces:# 在原彩色图上画人脸矩形框cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)# 获取该人脸矩形框的感兴趣区域RoI, 浅复制roi_gray = gray[y:y + h, x:x + w]roi_color = img[y:y + h, x:x + w]# 开始在人脸区域中检测眼睛,输出是眼睛区域的外接矩形框eyes = eye_cascade.detectMultiScale(roi_gray)# 遍历眼睛检测结构for (ex, ey, ew, eh) in eyes:# 在原彩色图上画眼睛矩形框cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
# 显示画好矩形框的图片
cv2.namedWindow('faces', cv2.WINDOW_AUTOSIZE)
cv2.imshow('faces', img)
# 等待退出键
cv2.waitKey(0)
# 销毁显示窗口
cv2.destroyAllWindows()
有关简单的神经网络
tf实现感知器
重要函数:
(1)
把版本切回tf2
tf.disable_v2_behavior()
(2)
Tensorflow的设计理念称之为计算流图,在编写程序时,首先构筑整个系统的graph,代码并不会直接生效,这一点和python的其他数值计算库(如Numpy等)不同,graph为静态的,类似于docker中的镜像。然后,在实际的运行时,启动一个session,程序才会真正的运行。这样做的好处就是:避免反复地切换底层程序实际运行的上下文,tensorflow帮你优化整个系统的代码。我们知道,很多python程序的底层为C语言或者其他语言,执行一行脚本,就要切换一次,是有成本的,tensorflow通过计算流图的方式,帮你优化整个session需要执行的代码,还是很有优势的。
而placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
tf.placeholder(dtype,shape=None,name=None
)
dtype:数据类型。常用的是tf.float32,tf.float64等数值类型
shape:数据形状。默认是None,就是一维值,也可以是多维(比如[2,3], [None, 3]表示列是3,行不定)
name:名称
tf.placeholder(tf.float32, [None, 2])
(3)
定义tf可使用的变量
可以看一下关于tf里面变量和运行的关系:
TensorFlow图变量tf.Variable的用法解析
tf.Variable(tf.random_normal([2, 1]), name='weight')sess.run(tf.global_variables_initializer())
(4)
优化器:
tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
源代码:
#!usr/bin/env python
# -*- coding:utf-8 _*-
import tensorflow.compat.v1 as tf
import numpy as nptf.disable_v2_behavior()tf.set_random_seed(777) # for reproducibility
learning_rate = 0.1x_data = [[0, 0],[0, 1],[1, 0],[1, 1]]
y_data = [[0],[1],[1],[0]]
x_data = np.array(x_data, dtype=np.float32)
y_data = np.array(y_data, dtype=np.float32)X = tf.placeholder(tf.float32, [None, 2])
Y = tf.placeholder(tf.float32, [None, 1])# 随机生成首次权重和偏置
W = tf.Variable(tf.random_normal([2, 1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')# 激活函数用sigmoid函数: tf.div(1., 1. + tf.exp(tf.matmul(X, W)))
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)# 目标函数或者说损失函数
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *tf.log(1 - hypothesis))train = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))# Launch graph
with tf.Session() as sess:# Initialize TensorFlow variablessess.run(tf.global_variables_initializer())for step in range(10001):sess.run(train, feed_dict={X: x_data, Y: y_data})if step % 100 == 0:print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run(W))# Accuracy reporth, c, a = sess.run([hypothesis, predicted, accuracy],feed_dict={X: x_data, Y: y_data})print("\nHypothesis: ", h, "\nCorrect: ", c, "\nAccuracy: ", a)'''
Hypothesis: [[ 0.5][ 0.5][ 0.5][ 0.5]]
Correct: [[ 0.][ 0.][ 0.][ 0.]]
Accuracy: 0.5
'''
tf实现简单的三层网络
重点在这一段,随机两层网络,并进行链接:
W1 = tf.Variable(tf.random_normal([2, 2]), name='weight1')
b1 = tf.Variable(tf.random_normal([2]), name='bias1')
layer1 = tf.sigmoid(tf.matmul(X, W1) + b1)W2 = tf.Variable(tf.random_normal([2, 1]), name='weight2')
b2 = tf.Variable(tf.random_normal([1]), name='bias2')
hypothesis = tf.sigmoid(tf.matmul(layer1, W2) + b2)
源代码:
#!usr/bin/env python
# -*- coding:utf-8 _*-
import tensorflow.compat.v1 as tf
import numpy as nptf.disable_v2_behavior()tf.set_random_seed(777) # for reproducibility
learning_rate = 0.1x_data = [[0, 0],[0, 1],[1, 0],[1, 1]]
y_data = [[0],[1],[1],[0]]
x_data = np.array(x_data, dtype=np.float32)
y_data = np.array(y_data, dtype=np.float32)X = tf.placeholder(tf.float32, [None, 2])
Y = tf.placeholder(tf.float32, [None, 1])W1 = tf.Variable(tf.random_normal([2, 2]), name='weight1')
b1 = tf.Variable(tf.random_normal([2]), name='bias1')
layer1 = tf.sigmoid(tf.matmul(X, W1) + b1)W2 = tf.Variable(tf.random_normal([2, 1]), name='weight2')
b2 = tf.Variable(tf.random_normal([1]), name='bias2')
hypothesis = tf.sigmoid(tf.matmul(layer1, W2) + b2)# cost/loss function
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *tf.log(1 - hypothesis))train = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))# Launch graph
with tf.Session() as sess:# Initialize TensorFlow variablessess.run(tf.global_variables_initializer())for step in range(10001):sess.run(train, feed_dict={X: x_data, Y: y_data})if step % 100 == 0:print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run([W1, W2]))# Accuracy reporth, c, a = sess.run([hypothesis, predicted, accuracy],feed_dict={X: x_data, Y: y_data})print("\nHypothesis: ", h, "\nCorrect: ", c, "\nAccuracy: ", a)
DIY一个简单的BP算例(双层网络)
import numpy as np# 定义双曲函数和他们的导数
def tanh(x):return np.tanh(x)def tanh_deriv(x):return 1.0 - np.tanh(x) ** 2def logistic(x):return 1 / (1 + np.exp(-x))def logistic_derivative(x):return logistic(x) * (1 - logistic(x))# 定义NeuralNetwork 神经网络算法
class NeuralNetwork:# 初始化,layes表示的是一个list,eg[10,10,3]表示第一层10个神经元,第二层10个神经元,第三层3个神经元def __init__(self, layers, activation='tanh'):""":param layers: A list containing the number of units in each layer.Should be at least two values:param activation: The activation function to be used. Can be"logistic" or "tanh""""if activation == 'logistic':self.activation = logisticself.activation_deriv = logistic_derivativeelif activation == 'tanh':self.activation = tanhself.activation_deriv = tanh_derivself.weights = []# 循环从1开始,相当于以第二层为基准,进行权重的初始化for i in range(1, len(layers) - 1):# 对当前神经节点的前驱赋值self.weights.append((2 * np.random.random((layers[i - 1] + 1, layers[i] + 1)) - 1) * 0.25)# 对当前神经节点的后继赋值self.weights.append((2 * np.random.random((layers[i] + 1, layers[i + 1])) - 1) * 0.25)# 训练函数 ,X矩阵,每行是一个实例 ,y是每个实例对应的结果,learning_rate 学习率,# epochs,表示抽样的方法对神经网络进行更新的最大次数def fit(self, X, y, learning_rate=0.1, epochs=10000):X = np.atleast_2d(X) # 确定X至少是二维的数据temp = np.ones([X.shape[0], X.shape[1] + 1]) # 初始化矩阵temp[:, 0:-1] = X # adding the bias unit to the input layerX = tempy = np.array(y) # 把list转换成array的形式for k in range(epochs):# 随机选取一行,对神经网络进行更新i = np.random.randint(X.shape[0])a = [X[i]]# 完成所有正向的更新for l in range(len(self.weights)):a.append(self.activation(np.dot(a[l], self.weights[l])))#error = y[i] - a[-1]deltas = [error * self.activation_deriv(a[-1])]if k % 1000 == 0:print(k, '...', error * error * 100)# 开始反向计算误差,更新权重for l in range(len(a) - 2, 0, -1): # we need to begin at the second to last layerdeltas.append(deltas[-1].dot(self.weights[l].T) * self.activation_deriv(a[l]))deltas.reverse()for i in range(len(self.weights)):layer = np.atleast_2d(a[i])delta = np.atleast_2d(deltas[i])self.weights[i] += learning_rate * layer.T.dot(delta)# 预测函数def predict(self, x):x = np.array(x)temp = np.ones(x.shape[0] + 1)temp[0:-1] = xa = tempfor l in range(0, len(self.weights)):a = self.activation(np.dot(a, self.weights[l]))return aif __name__ == "__main__":nn = NeuralNetwork([2, 2, 1], 'tanh')X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])y = np.array([0, 1, 1, 0])nn.fit(X, y)for i in [[0, 0], [0, 1], [1, 0], [1, 1]]:print(i, nn.predict(i))
简单的CNN例子
from __future__ import division, print_function, absolute_import# Import MNIST data,MNIST数据集导入
from tensorflow_core.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets("/tmp/data/", one_hot=False)#import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import matplotlib.pyplot as plt
import numpy as np# In[2]:# Training Parameters,超参数
learning_rate = 0.001 # 学习率
num_steps = 2000 # 训练步数
batch_size = 128 # 训练数据批的大小# Network Parameters,网络参数
num_input = 784 # MNIST数据输入 (img shape: 28*28)
num_classes = 10 # MNIST所有类别 (0-9 digits)
dropout = 0.75 # Dropout, probability to keep units,保留神经元相应的概率# In[3]:# Create the neural network,创建深度神经网络
def conv_net(x_dict, n_classes, dropout, reuse, is_training):# Define a scope for reusing the variables,确定命名空间with tf.variable_scope('ConvNet', reuse=reuse):# TF Estimator类型的输入为像素x = x_dict['images']# MNIST数据输入格式为一位向量,包含784个特征 (28*28像素)# 用reshape函数改变形状以匹配图像的尺寸 [高 x 宽 x 通道数]# 输入张量的尺度为四维: [(每一)批数据的数目, 高,宽,通道数]x = tf.reshape(x, shape=[-1, 28, 28, 1])# 卷积层,32个卷积核,尺寸为5x5conv1 = tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu)# 最大池化层,步长为2,无需学习任何参量conv1 = tf.layers.max_pooling2d(conv1, 2, 2)# 卷积层,32个卷积核,尺寸为5x5conv2 = tf.layers.conv2d(conv1, 64, 3, activation=tf.nn.relu)# 最大池化层,步长为2,无需学习任何参量conv2 = tf.layers.max_pooling2d(conv2, 2, 2)# 展开特征为一维向量,以输入全连接层# fc1 = tf.contrib.layers.flatten(conv2)fc1 = tf.layers.flatten(conv2)# 全连接层fc1 = tf.layers.dense(fc1, 1024)# 应用Dropout (训练时打开,测试时关闭)fc1 = tf.layers.dropout(fc1, rate=dropout, training=is_training)# 输出层,预测类别out = tf.layers.dense(fc1, n_classes)return out# In[4]:# 确定模型功能 (参照TF Estimator模版)
def model_fn(features, labels, mode):# 构建神经网络# 因为dropout在训练与测试时的特性不一,我们此处为训练和测试过程创建两个独立但共享权值的计算图logits_train = conv_net(features, num_classes, dropout, reuse=False, is_training=True)logits_test = conv_net(features, num_classes, dropout, reuse=True, is_training=False)# 预测pred_classes = tf.argmax(logits_test, axis=1)pred_probas = tf.nn.softmax(logits_test)if mode == tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode, predictions=pred_classes)# 确定误差函数与优化器loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_train, labels=tf.cast(labels, dtype=tf.int32)))optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)train_op = optimizer.minimize(loss_op, global_step=tf.train.get_global_step())# 评估模型精确度acc_op = tf.metrics.accuracy(labels=labels, predictions=pred_classes)# TF Estimators需要返回EstimatorSpecestim_specs = tf.estimator.EstimatorSpec(mode=mode,predictions=pred_classes,loss=loss_op,train_op=train_op,eval_metric_ops={'accuracy': acc_op})return estim_specs# In[5]:# 构建Estimator
model = tf.estimator.Estimator(model_fn)# In[6]:# 确定训练输入函数
input_fn = tf.estimator.inputs.numpy_input_fn(x={'images': mnist.train.images}, y=mnist.train.labels,batch_size=batch_size, num_epochs=None, shuffle=True)
# 开始训练模型
model.train(input_fn, steps=num_steps)# In[7]:# 评判模型
# 确定评判用输入函数
input_fn = tf.estimator.inputs.numpy_input_fn(x={'images': mnist.test.images}, y=mnist.test.labels,batch_size=batch_size, shuffle=False)
model.evaluate(input_fn)# In[8]:# 预测单个图像
n_images = 4
# 从数据集得到测试图像
test_images = mnist.test.images[:n_images]
# 准备输入数据
input_fn = tf.estimator.inputs.numpy_input_fn(x={'images': test_images}, shuffle=False)
# 用训练好的模型预测图片类别
preds = list(model.predict(input_fn))# 可视化显示
for i in range(n_images):plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray')plt.show()print("Model prediction:", preds[i])
0118-深度学习基础及一些代码实例相关推荐
- 人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 编程指南
编程指南 目前飞桨(PaddlePaddle,以下简称Paddle)已经同时支持动态图和静态图两种编程方式, 本文主要侧重于介绍静态图的编程方法,关于动态图编程方法,请参考动态图机制-DyGraph. ...
- 第三章_深度学习基础
文章目录 第三章 深度学习基础 3.1 基本概念 3.1.1 神经网络组成? 3.1.2神经网络有哪些常用模型结构? 3.1.3如何选择深度学习开发平台? 3.1.4为什么使用深层表示? 3.1.5为 ...
- 五万字总结,深度学习基础。
文章目录 1 基本概念 1.1 神经网络组成? 1.2 神经网络有哪些常用模型结构? 1.3 如何选择深度学习开发平台? 1.4 为什么深层神经网络难以训练? 1.5 深度学习和机器学习的异同? 2 ...
- 深度学习基础知识每日更 upupup
深度学习基础知识点总结 提示:菜鸟入门日记,若总结有错误,各路大佬多多指教! 文章目录 深度学习基础知识点总结 Looking for my friends 一.零散知识点 1.网络拼接和相加的区别 ...
- 第3章(3.11~3.16节)模型细节/Kaggle实战【深度学习基础】--动手学深度学习【Tensorflow2.0版本】
项目地址:https://github.com/TrickyGo/Dive-into-DL-TensorFlow2.0 UC 伯克利李沐的<动手学深度学习>开源书一经推出便广受好评.很多开 ...
- 日月光华深度学习(一、二)深度学习基础和tf.keras
日月光华深度学习(一.二)深度学习基础和tf.keras [2.2]--tf.keras实现线性回归 [2.5]--多层感知器(神经网络)的代码实现 [2.6]--逻辑回归与交叉熵 [2.7]--逻辑 ...
- 深度学习基础篇【5】从0开始搭建YOLOV5 并进行测试
深度学习基础篇[5] 从0开始搭建 YOLOV5 并进行测试 如何评价YOLO V5,那就必须拿"上一代"YOLO V4来做对照了.先说结论,YOLO V5 在性能上稍弱于YOL ...
- 第二次作业:“深度学习基础”
第二次作业:"深度学习基础" 完成一篇博客,题目为 " 第二次作业:深度学习基础 " 第二次软工作业 第二次作业:"深度学习基础" 一.视频 ...
- 深度学习基础(基本概念、优化算法、初始化、正则化等)
2020-04-25 16:29:09 引言 深度学习目前已成为发展最快.最令人兴奋的机器学习领域之一,许多卓有建树的论文已经发表,而且已有很多高质量的开源深度学习框架可供使用.然而,论文通常非常简明 ...
最新文章
- appium 控件定位
- iOS性能优化 - 网络图片加载优化
- 偷懒的inline-block解决方法
- 在Python中使用lightgbm
- CentOS的改变系统启动级别
- Flink分布式standalone部署方式(第一种方式)
- ubuntu apt-mirror 同步源到本地
- [BZOJ1643][Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪
- 活动目录实战系列七(降级主DC为成员服务器)
- WPF TextBox 正则验证 大于等于0 小于等于1 的两位小数
- USB On-The-Go引脚
- Java使用easyExcel操作Excel案例
- python 3.7 安装 win32 win32com win32ras模块
- java数字金额大写金额_Java实现 将数字金额转为大写中文金额
- html鼠标悬停多个效果,33个jQuery与CSS3实现的绚丽鼠标悬停效果
- python中实现简单抽样的函数
- SQL Server 索引中的碎片和填充因子
- Android系统默认Home应用程序 Launcher 的启动过程源代码分析
- 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)
- 计算机专业对应的职业群有,[计算机硬件及网络]7k专业与职业群.ppt