基础篇:简单神经网络模型的构建

文章目录

      • 1.TensorFlow基础知识
        • 1.张量的构建
        • 2.张量的转换
        • 3.张量的运算
      • 2.神经网络模型建立
        • 1.线性神经网络
        • 2.激活函数
        • 3.损失函数
        • 4.优化器
        • 5.构建神经网络模型
        • 6.梯度消失与梯度爆炸

1.TensorFlow基础知识

1.张量的构建

1.构建0维张量

  import tensorflow as tf
  rank_0_tensor = tf.constant(6.0)  #构建0维张量
  print(rank_0_tensor)

2.构建1维张量

  rank_1_tensor = tf.constant([1.0,2.0,3.0])  #构建1维张量  
  print(rank_1_tensor)

3.构建2维张量

  rank_2_tensor = tf.constant([[1.0,2.0,3.0],
                               [4.0,5.0,6.0]])  #构建2维张量  
  print(rank_2_tensor)

4.构建3维张量

  rank_3_tensor = tf.constant([[[0,1,2,3],[4,5,6,7]],
                             [[8,9,10,11],[12,13,14,15]],
                             [[16,17,18,19],[20,21,22,23]]])  #构建3维张量  
  print(rank_3_tensor)

2.张量的转换

1.张量转换数组

  import numpy as np
  a = np.array(rank_3_tensor)  #张量转换数组    
  print(a)
  # 数组转换张量
  # rank_3_tensor=tf.constant(a) 

2.张量形状改变

  rank_3_tensor = tf.reshape(rank_3_tensor,[6,4])  #改变张量形状  
  print(rank_3_tensor)

3.列表转换不规则张量

  ragged_list= [
      [0,1,2,3],
      [4,5],
      [6,7,8],
      [9]]  #创建列表
  ragged_tensor = tf.ragged.constant(ragged_list)  #将列表转换不规则张量
  print(ragged_tensor)
  print(ragged_tensor.shape)  #输出张量形状

4.稀疏张量转换为普通张量

  # 创建稀疏张量
  space_tensor = tf.sparse.SparseTensor(indices = [[0,0],[1,2]],  #不为零的位置
                                       values = [1,2],  #不为零的取值
                                       dense_shape = [3,4])   #张量形状
  print(space_tensor)   
  print(tf.sparse.to_dense(space_tensor))  #稀疏张量转换普通张量

3.张量的运算

1.张量基础运算

  a = tf.constant([[1,2],
                [3,4]])
  b = tf.constant(a)
  print(a+b)  #张量基本运算
  print(a-b)
  print(a*b)
  print(a@b)  #矩阵乘法
  print(a/b)
  print(tf.add(a,b))  #张量相加
  print(tf.subtract(a,b))  #张量相减
  print(tf.multiply(a,b))  #张量相乘
  print(tf.matmul(a,b))  #张量矩阵乘法
  print(tf.divide(a,b))  #张量相除
  c=tf.constant([[0.5,0.6],
                 [0.7,0.8]])
  print(tf.math.log(c))  #求张量的底数为e的对数

2.张量求导

  x = tf.Variable(initial_value = 3.0)  #变量初始值为3
  with tf.GradientTape() as tape:
      y = tf.square(x)  #y等于x的平方
  y_grad =  tape.gradient(y,x)  #计算y关于x的导数
  print(y,y_grad)

2.神经网络模型建立

1.线性神经网络

  from tensorflow import keras
  from tensorflow.keras import layers
  model_test = keras.Sequential(  #构建线性神经网络模型
      [
          keras.Input(shape = (2)),  #第一层,设置输入值数量shape
          layers.Dense(4,name = 'hidden_layer'),  #第二层,设置层名称name及数目
          layers.Dense(1,name = 'output_lay')  #第三层
       ]
  )
  print(model_test.summary())  #输出整个模型概述
  print(model_test.weights)  #输出模型属性
  test = [[1,0]]
  print(model_test.predict(test))  #输出模型预测值

2.激活函数

常用的激活函数
1.linear f ( x ) = x f(x)=x f(x)=x
2.exponential f ( x ) = e x f(x)=e^{x} f(x)=ex
3.sigmoid f ( x ) = 1 1 + e − x f(x)=\frac{1}{1+e^{-x}} f(x)=1+ex1
4.softmax f ( x ) = e x i ∑ j e x j f(x)=\frac{e^{x_{i}}}{ {\textstyle \sum_{j}^{}} e^{x_{j}}} f(x)=jexjexi
5.tanh f ( x ) = 1 − e − 2 x 1 + e − 2 x f(x)=\frac{1-e^{-2x}}{1+e^{-2x}} f(x)=1+e2x1e2x
6.ReLU(计算简单,代表性稀疏,线性)
f ( x ) = { 0 , ( x < 0 ) x , ( x ≥ 0 ) f(x)=\begin{cases}0,(x<0)\\x,(x\ge0)\end{cases} f(x)={0,(x<0)x,(x0)
7.ELU(解决神经元坏死现象)
f ( x ) = { α ( e x − 1 ) ( x < 0 ) x ( x ≥ 0 ) f(x)=\begin{cases}\alpha (e^{x}-1)&(x<0) \\x&(x\ge0) \end{cases} f(x)={α(ex1)x(x<0)(x0)

  model = keras.Sequential(  #构建神经网络模型
      [
          keras.Input(shape = (2)),  #第一层,设置输入数量shape
          layers.Dense(4,activation = 'sigmoid',name = 'hidden_layer'),  #第二层,设置层名称name,激活函数sigmoid
          layers.Dense(1,activation = 'sigmoid',name = 'output_lay')  #第三层,输出层
       ]
  )

3.损失函数

   用于定量描述实际值与预测值之间的差距。
   通常选择非负数作为损失函数,差距越小损失函数越小,完美模型的损失函数为0。
1.均方误差(mean_squared_error)
L ( M S E ) = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 L(MSE)=\frac{1}{n}\sum_{i=1}^{n}(\hat{y}_{i}-y_{i})^{2} L(MSE)=n1i=1n(y^iyi)2
2.平均绝对误差(mean_absolute_error)
L ( M A E ) = 1 n ∑ i = 1 n ∣ y ^ i − y i ∣ L(MAE)=\frac{1}{n}\sum_{i=1}^{n}\left|\hat{y}_{i}-y_{i}\right| L(MAE)=n1i=1ny^iyi
3.平均绝对百分比误差(mean_squared_percentage_error)
L ( M A P E ) = 1 n ∑ i = 1 n ∣ y ^ i − y i ∣ y i × 100 L(MAPE)=\frac{1}{n}\sum_{i=1}^{n}\frac{\left|\hat{y}_{i}-y_{i}\right|}{y_{i}}\times 100 L(MAPE)=n1i=1nyiy^iyi×100
4.均方对数误差(mean_squared_logarithmic_error)
L ( M S L E ) = 1 n ∑ i = 1 n ( l o g ( y ^ i + 1 ) − l o g ( y i + 1 ) ) 2 L(MSLE)=\frac{1}{n}\sum_{i=1}^{n}\left(log\left(\hat{y}_{i}+1\right)-log\left(y_{i}+1\right)\right)^{2} L(MSLE)=n1i=1n(log(y^i+1)log(yi+1))2
5.双曲余弦对数(logcosh)
L ( l o g c o s h ) = 1 n ∑ i = 1 n l o g ( c o s h ( y ^ i − y i ) ) L(logcosh)=\frac{1}{n}\sum_{i=1}^{n}log\left(cosh\left(\hat{y}_{i}-y_{i}\right)\right) L(logcosh)=n1i=1nlog(cosh(y^iyi))

4.优化器

方法 优点 缺点 适应情形 备注
梯度下降(Gradient Descent,GD) 对凸函数可能找到全局最优解 大体系计算速度慢 较小的网络 短的步长不易发生振荡,长的步长收敛速度快
动量(Momentum) 抑制振荡,加快收敛 不能实时更新模型 有可靠的初始化参数 下降更快,窄长梯度减少振荡
Nesterov Accelerated Gradient(NAG) 抑制振荡,加快收敛 不能实时更新模型 有可靠的初始化参数 预估修正
自适应梯度(Adaptive Gradient,AdaGrad) 实时更新学习率 学习率衰减行为激进 需要快速收敛,梯度稀疏 通过使用全局学习率除以历史梯度平方和的平方根,达到实时自动修改学习率的目的
均方根反向传播(RMSProp) 实时更新学习率,避免学习率过快衰减 需要全局学习率 多数情况,复杂网络效果好 摒弃了较远的梯度历史,根据经验,RMSProp是一种较为实用的深度学习网络优化算法
自适应矩估计(Adaptive Moment Estimation,Adam) 实时更新,收敛快 复杂 多数情形 本质:带有动量项的RMSProp,实时调整学习率,Adam适用于多数优化情形,且效果好

5.构建神经网络模型

  import tensorflow as tf
  import numpy as np
  model.compile(optimizer = 'adam',  #模型优化器adam方法
                loss = 'mean_spuared_errror',  #模型损失函数mean spuared errror(MSE)
                metrics = ['accuracy'])  #评估标准,accuracy预测准确度
                
  x_train = [[0,0],  #定义x y训练集
           [1,0],
           [0,1],
           [1,1]]
  y_train = [0,1,1,0]
  x_train = tf.constant(x_train)  #将训练集转换为张量形式
  y_train = tf.constant(y_train)
  
  model.fit(x_train,y_train,epochs = 2000,verbose = 0)  #开始训练模型,2000次,verbose用于控制拟合过程的输出(默认1,0不输出,1带进度条输出,2不带进度条输出)
  model.evaluate(x_train,y_train)  #模型评价
  
  res = model.predict(x_train)  #模型预测,返回预测数组
  print(res)  
  for i in res:
      print(np.round(i))  #将预测值四舍五入 
  import matplotlib.pyplot as plt
  from matplotlib.colors import ListedColormap
  #拟合数据可视化
  xx,yy = np.meshgrid(np.linspace(-0.5,1.5,200),np.linspace(-0.5,1.5,200))
  # np.linspace(start,stop,num) 创建等差数列构成的一维数组,范围start到stop,有num个
  # np.meshgrid() 从坐标数组中创建坐标矩阵
  coords = np.stack((xx.reshape(-1),yy.reshape(-1)),axis = -1)
  # np.stack() 沿特定轴连接数组序列,axis = -1沿最后一个轴
  # reshape(-1) 数组变为一行
  Z = model.predict(coords)
  Z = np.round(Z).reshape(xx.shape)

  light_rgb = ListedColormap(['lightcyan','mistyrose'])
  # ListedColormap()从颜色列表创建colormap对象 lightcyan淡青色(225,255,255) mistyrose薄雾玫瑰(255,228,225)

  num_epoch = np.arange(0,3000,300)  #从0到3000每隔300创建一维数组
  plt.figure(figsize = (25,10))  #设置绘图参数,figsize宽高的尺寸,单位英寸
  for i in range(10):
      model.fit(x_train,y_train,epochs = num_epoch[i],verbose = 0)
      Z = model.predict(coords)
      Z = np.round(Z).reshape(xx.shape)
      plt.subplot(2,5,i+1)  #绘制子图,行数,列数,子图位置
      plt.pcolormesh(xx,yy,Z,cmap = light_rgb)  #pcolormesh()函数创建伪彩色图,cmap设置颜色
      plt.scatter([0,1],[1,0],c = 'r',s = 300, edgecolor = 'k')  #plt.scatter()绘制散点图,c设置颜色,s散点大小,edgecolor边缘颜色
      plt.scatter([0,1],[0,1],c = 'darkcyan',s = 300,edgecolor = 'k')
  plt.show()  #显示绘图

6.梯度消失与梯度爆炸

  • 梯度消失
    a b s ( w f ′ ( x ) ) < 1 abs(wf'(x))<1 abs(wf(x))<1
  • 梯度爆炸
    a b s ( w f ′ ( x ) ) > 1 abs(wf'(x))>1 abs(wf(x))>1
    原因:隐藏层数目过多,根本原因在于反向传播
    解决方法:选择合适的激活函数

你可能感兴趣的:(机器学习,python)