分别生成斐波那契数列的第40个元素、第48个元素_深度学习入门 | 第3章:神经网络的TensorFlow实现(1)...

97d2f77f13b4664c5ed82ccc8f5930ab.png

点击关注了解更多精彩内容!!

导言

通过前面两章的学习,不知道是否消除了大家对于深度学习的恐惧。如果此时你仍然不知道如何实现深度学习模型,请不要着急,学完本章,你将可以实现自己的第一个深度学习模型。

从本章开始,将全面进入神经网络的编程实践部分。在具体实践之前,需要一些预备知识。首先介绍神经网络的基本数据结构:张量的概念及其分类。张量将会贯穿整个深度学习,因此对它的掌握非常重要。其次,深度学习最擅长的领域之一就是图像处理,我们将重点介绍图像数据的处理与应用。具备这些预备知识后,本章将给出两个基于TensorFlow实现的神经网络的例子,第一个是美食图像评分,通过线性回归解决;第二个是手写数字识别,通过逻辑回归解决。

3.1神经网络的数据结构

在构建和训练一个神经网络之前,需要了解神经网络的基本数据结构,接下来大家将学到张量的概念。

3.1.1 张量及其分类

张量(Tensor)可以理解为a394303da0054c4fbe95628cab2363be.png维数组或矩阵。根据维数的不同,张量又可以分为标量、向量、矩阵、3D张量及更高维张量。

1.标量

标量(0D张量)是指仅包含一个数字的张量,又称零维张量,0D张量。在Numpy数组中,一个float32或float64的数字就是一个标量,可以用ndim查看张量的维度,下面是一个Numpy标量示例。

import numpy as np
x = np.array(888)
print(x)
print(x.ndim)

输出:

888
0

2.向量

向量(1D张量)是指由数字组成的数组,也称为一维张量,1D张量。下面是一个Numpy向量示例。

x = np.array([1,2,3,4,5])
print(x)
x.ndim

输出:

[1 2 3 4 5]
1

3.矩阵

矩阵(2D张量)是指由向量组成的数组,也称为二维张量,2D张量,矩阵有2个维度,一个是行,一个是列,下面是一个Numpy矩阵示例。

x = np.array([[1,2,3,4],
              [5,6,7,8],
              [9,6,7,4]])
print(x)
x.ndim

输出:

[[1 2 3 4]
 [5 6 7 8]
 [9 6 7 4]]
2

4. 3D张量与更高维张量

3D张量与更高维张量,是指由多个矩阵组成的数组,可以理解为关于数字的三维立体矩阵。下面是一个Numpy的3D张量示例。

x = np.array([[[12,4,6,8,23],
               [45,1,2,6,67]],
              [[32,7,3,5,14],
               [56,1,2,8,18]],
              [[23,7,2,5,78],
               [14,2,7,2,15]]])
print(x)
x.ndim

输出:

[[[12 4 6 8 23]
  [45 1 2 6 67]] 
 [[32 7 3 5 14] 
  [56 1 2 8 18]] 
 [[23 7 2 5 78] 
  [14 2 7 2 15]]]
3

将多个3D张量组合成一个数组,就可以创建4D张量,以此类推,可以创建更高维的张量。

3.1.2 张量数据示例

1. 2D张量数据示例:向量数据

向量数据是最常见的数据类型,存储形状为(Samples,Features),第一个参数代表样本数,第二个参数代表特征数。例如:

(1)学生成绩数据。其中包括每个学生数学、语文和外语3门课的分数,每个人可以表示成包含3个值的向量,假设数据有100个人,那么这将存储在形状为(100,3)的2D张量中。

(2)家庭收入数据。其中包括每个家庭的税前收入和税后收入,每个家庭可以表示成包含2个值的向量,假设有1,000个家庭,那么这将存储在形状为(1000,2)的2D张量中。

2. 3D张量数据示例:时间序列数据

时间序列数据被存储在带有时间维度的3D张量中,存储形状为(Samples,Timesteps,Features),第一个参数代表样本数,第二个参数代表时间步长,第三个参数代表特征数。例子如下:

(1)各省份宏观经济数据。记录1978-2018年全国34个省份每年的宏观经济数据,包括GDP、CPI和FDI。每个省份的数据都被编码为一个形状为(40,3)的2D张量(因为记录的是40年的数据),而全国34个省份的数据可以保存在一个形状为(34,40,3)的3D张量中。这里的每个样本是每个省份过去40年的宏观经济数据。

(2)股票价格数据。假设现在需要记录250个交易日500只股票每天的开盘价、收盘价、最高价和最低价,每只股票的数据会被编码成一个形状为(250,4)的2D张量(因为一只股票有250个交易日),则500只股票的数据可以保存在一个形状为(500,250,4)的3D张量中。

3. 4D张量数据示例:图像数据

图像数据是个4D张量,存储形状为(Samples,Height,Width,Channels),第一个参数代表样本数,第二个是图像的高度,第三个是图像的宽度,第四个是图像的颜色深度,也称为通道数。

如果不关注第一个参数samples,则一张图像数据就是一个三维立体矩阵。在电子图像中,不用图像的几何尺寸来表示图像,而是用图像的像素尺寸。通俗地说,一像素对应显示器的一个发光单元,一个图像的像素尺寸,就指定了这张图像需要使用显示器中的多少个发光单元,像素尺寸越大,图像包含的细节越多。例如,图3.1这张熊大的图像,就是一个为301像素×296像素×3的原图。

72669426b533a4c0266cec4899b34453.png

图3.1 图像数据示例:熊大

这说明,图3.1的图像是由3个像素尺寸为89,096的像素矩阵组成的,每个像素矩阵以301行296列的形式排列。每个像素点表达不同的颜色以及深浅,然后形成了我们看到的这个图像。那么如何表达每个像素点颜色的深浅?

光学知识告诉我们,白光可以被分解成红绿蓝(RGB)3种基色,通过3种光的混合,能生成各种颜色。这说明,任何一个像素点颜色的深浅,其实是3种基色混合而成的。因此,要表达一个像素点颜色的深浅,需要一个长度为3的向量。该向量的3个元素分别对应3种基色。其数值大小,对应了该基色的深浅。

例子如下。

(1)对于灰度图像,只有一个颜色通道,假设图像像素矩阵大小是128像素×128像素,那么100张灰度图像可以保存在一个形状为(100,128,128,1)的张量中。

(2)对于彩色图像,因为有3个颜色通道(分别为R、G、B),同样,100张大小为128像素×128像素的彩色图像会被存储在形状为(100,128,128,3)的张量中。

3.2 图像数据的存储与运算

通过前面的学习我们知道,深度学习非常善于处理非结构化数据,如图像、文本、声音等。作为入门,先从图像数据开始介绍,主要原因有三个:(1)基于图像数据的应用特别多;(2)有很多大量的、公开的图像数据供学者研究;(3)相比于其他非结构化数据,更容易上手学习。

本节将介绍有关图像数据的存储和运算。

3.2.1图像数据的读入与展示

1. 读入图像

首先通过程序读入图像xiongda.jpg并将其展示出来,处理图像数据需要载入Image包,其中.open函数用于打开图像数据。具体如代码示例3-1所示。

代码示例3-1

from PIL import Image
photo = Image.open('./photos/xiongda.jpg')
photo

输出:

94523170e1dea44b70e91d35c82209ba.png

2. 改变大小

接下来可以通过.size函数查看原始图像的大小,并通过.resize函数改变图像的大小。可以看到,原始图像的大小是301像素×296像素。在实际数据分析中,不同图像的大小规格会不一样,为了后续对图像处理的方便,通常将其统一规格,本例将其统一为128像素×128像素大小。具体如代码示例3-2所示。

代码示例3-2

print(photo.size)
photo=photo.resize([128,128])
print(photo.size)
photo

输出:

(301, 296)
(128, 128)

3bdab7369a6b992bc91c724e3b7e00b5.png

3. 矩阵转换

将图像数据通过.array转换为矩阵形式。通过.array函数,把图像数据转换为一个128像素×128像素×3的张量,其中3代表彩色图像有3个颜色通道,将第0个通道(注意Python的索引是从0开始的)的矩阵大小展示出来,就会看到如下所示简化的矩阵。至此,就将一张图像转换成一个三维立体矩阵,方便后续进行各种代数计算。具体如代码示例3-3所示。

代码示例3-3

import numpy as np
Im=np.array(photo)
print(Im.shape)
Im[:,:,0]

输出:

 (128, 128, 3)
array([[255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       ...,
       [ 42,  36,  44, ...,  53,  57,  49],
       [ 33,  30, 152, ...,  52,  53,  48],
       [ 28, 150, 255, ...,  54,  50,  40]], dtype=uint8)

4. 尺度变化

在TensorFlow和Keras中,人们要求图像的像素矩阵的大小为0-1,而刚刚代码示例3-3输出的三维立体矩阵,每个元素的取值大小为0-255,因此为了处理方便,需要变换原始像素矩阵的尺度,将每个元素取值除以255。具体如代码示例3-4所示。

代码示例3-4

Im=Im/255
print(Im[:,:,0])

输出:

 [[1.         1.         1.         ... 1.         1.         1.        ]
 [1.         1.         1.         ... 1.         1.         1.        ]
 [1.         1.         1.         ... 1.         1.         1.        ]
 ...
 [0.16470588 0.14117647 0.17254902 ... 0.20784314 0.22352941 0.19215686]
 [0.12941176 0.11764706 0.59607843 ... 0.20392157 0.20784314 0.18823529]
 [0.10980392 0.58823529 1.         ... 0.21176471 0.19607843 0.15686275]]

5.图像展示

经过前面几个步骤的处理,最开始的图像现在变成了一个三维立体矩阵,用Im表示,接下来需要通过.imshow函数告诉计算机将三维立体矩阵展示成图像形式。具体如代码示例3-5所示。

代码示例3-5

from matplotlib import pyplot as plt
plt.imshow(Im)

输出:

3aee9177f9b7302b6db3eeba5555d7cc.png

3.2.2 图像数据的代数运算

图像数据转换成三维立体矩阵之后,意味着可以对图像数据进行基本的代数运算,下面通过例子对图像数据进行加法、减法、乘法和除法运算。具体如代码示例3-6所示。

代码示例3-6

Im1=Im+0.5
Im2=1-Im
Im3=0.5*Im
Im4=Im/0.5
plt.figure()
fig,ax=plt.subplots(1,4)
fig.set_figwidth(15)
ax[0].imshow(Im1)
ax[1].imshow(Im2)
ax[2].imshow(Im3)
ax[3].imshow(Im4)

输出:

06bc117a82461cad7f7537eddfb43636.png

第1张图像将Im图像加上0.5得到Im1。

第2张图像用1减去Im图像得到Im2。

第3张图像用0.5乘以Im图像得到Im3。

第4张图像将Im图像除以0.5得到Im4。

将这4张图像(Im1,Im2,Im3和Im4)展示在一张画板上,.figure函数用于初始化画板,.subplots函数用于切分画板,这里切分成了1行4列。切分之后会有两个输出,其中fig可以控制画板的长和宽,例如,这里设置.set_figwidth宽度为15个单位。ax可以控制图像的位置,索引从0开始,例如,将Im0放在最左边,以此类推。

这个例子将图像进行了简单的加、减、乘、除运算,可能没有什么特别的实际意义,但是可以帮助我们更加直观地理解图像数据的代数运算。

168b99c2142fa5df92630270c5521f9e.png往期精彩第1章:深度学习简介第2章:神经网络基础(1)第2章:神经网络基础(2)点击这里阅读原文
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值