神经网络模型常见的损失函数
1.神经网络模型简介
神经网络模型一般包含输入层、隐含层和输出层,每一层都是由诸多神经元组成。输入层神经元的个数一般和输入模型的特征(单个样本的维数)有关,输出层神经元的个数与项目任务有关,隐含层的个数一般根据经验设置即可。
对于神经网络模型而言,根据不同的输出任务而言,可以分成模式分类和模式回归两大问题。在训练神经网络时,往往采用基于梯度下降的方法不断去缩小预测值和真实值之间的差值,而这个差值就叫做损失(Loss),计算该损失的函数就叫做损失函数(Loss function)。对于不同输出类型的神经网络模型,其损失函数是不同的,损失函数和输出层的激励函数是相互配套使用的。
2.神经网络模型常见的损失函数
(1)回归任务
输出层神经元个数:1个
损失函数:
MSE(均方误差)
M S E = 1 n ∑ i = 1 n ( f i − y i ) 2 . MSE = \frac{1}{n}\sum_{i=1}^{n}(f_{i}-y_{i})^{2}. MSE=n1i=1∑n(fi−yi)2.
其中f是模型的预测值,y是样本的真实值。
输出层配套的激活函数:
linear、sigmoid、tanh等均可以
(2)分类任务
分类任务包含二分类和多分类问题。
a.二分类任务:
二分类任务根据不同的损失函数分成两种:
- 输出神经元个数2个:
损失函数:binary_crossentropy
二分类交叉熵损失函数:
L o s s = − 1 n ∑ i = 1 n y i ( l n a ) + ( 1 − y i ) l n ( 1 − a ) Loss= -\frac{1}{n}\sum_{i=1}^{n} y_{i}(lna)+(1-y_{i})ln(1-a) Loss=−n1i=1∑nyi(lna)+(1−yi)ln(1−a) 其 中 : a = − 1 1 + e − x 其中:a= -\frac{1}{1+e^{-x}} 其中:a=−1+e−x1
输出层配套的激活函数:softmax
S i = − e i ∑ j e j S_{i}= -\frac{e^{i}}{\sum_{j}e^{j}} Si=−∑jejei
此处的图是多分类的,二分类时只有两个神经元,输出的就是样本对应类别的概率,如两个神经元分别输出0.88和0.12,此时样本对应的类别就是0.88对应的类别。
- 输出神经元个数1个:
损失函数:binary_crossentropy
二分类交叉熵损失函数:
L o s s = − 1 n ∑ i = 1 n y i ( l n a ) + ( 1 − y i ) l n ( 1 − a ) Loss= -\frac{1}{n}\sum_{i=1}^{n} y_{i}(lna)+(1-y_{i})ln(1-a) Loss=−n1i=1∑nyi(lna)+(1−yi)ln(1−a) 其 中 : a = − 1 1 + e − x 其中:a= -\frac{1}{1+e^{-x}} 其中:a=−1+e−x1
输出层配套的激活函数:sigmoid或者tanh
需要注意的是此时的损失函数(二分类交叉熵)要求训练样本的标签必须为独热编码(one-hot).此时的输出的编码为1或者0.
s i m o i d 函 数 : σ ( z ) = 1 1 + e − z simoid函数:\sigma(z) = \frac{1}{1+e^{-z}} simoid函数:σ(z)=1+e−z1 t a n h 函 数 : t a n h ( z ) = e x − e − x e x + e − x tanh函数:tanh(z) = \frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} tanh函数:tanh(z)=ex+e−xex−e−x
b.多分类任务
多分类任务的输出神经元个数和输出的类别有关,几种类别对应着几个输出神经元,根据损失函数的不同可以分为两类:
categorical_crossentropy(多分类交叉熵损失函数)
损失函数:
categorical_crossentropy(多分类交叉熵损失函数)
l o s s = − ∑ i = 1 n f i 1 l o g y i 1 + f i 2 l o g y i 2 + . . + f i m l o g y i m . loss = -\sum_{i=1}^{n}f_{i1}logy_{i1}+f_{i2}logy_{i2}+..+f_{im}logy_{im}. loss=−i=1∑nfi1logyi1+fi2logyi2+..+fimlogyim.
其中n是样本数目,m是分类数。
输出层配套的激活函数:softmax
输出层神经元个数:几个分类对应着几个神经元数目
需要注意的是这个损失函数(多分类损失函数)要求训练样本的标签必须为独热编码sparse_categorical_crossentropy(多分类交叉熵损失函数)
损失函数:
sparse_categorical_crossentropy(稀疏多分类交叉熵损失函数)
l o s s = − ∑ i = 1 n f i 1 l o g y i 1 + f i 2 l o g y i 2 + . . + f i m l o g y i m . loss = -\sum_{i=1}^{n}f_{i1}logy_{i1}+f_{i2}logy_{i2}+..+f_{im}logy_{im}. loss=−i=1∑nfi1logyi1+fi2logyi2+..+fimlogyim.
其中n是样本数目,m是分类数。
输出层配套的激活函数:softmax
输出层神经元个数:几个分类对应着几个神经元数目
需要注意的是这个损失函数(多分类损失函数)要求训练样本的标签必须为数字编码
【注意】两种损失函数的区别可以参考:这篇博客(博主是AI剑客).
tensorflow 与keras里面的损失函数:categorical_crossentropy VS. sparse_categorical_crossentropy区别:
两者都是多分类交叉熵损失函数,区别在于sparse(稀疏),在于对target编码的要求。
1.categorical_crossentropy要求target为onehot编码。
2.sparse_categorical_crossentropy要求target为非onehot编码,函数内部进行onehot编码实现。
例如:
如果你的 targets 是 one-hot 编码,用 categorical_crossentropy
one-hot 编码:[0, 0, 1],
[1, 0, 0],
[0, 1, 0]
如果你的 tagets 是 数字编码 ,用 sparse_categorical_crossentropy
数字编码:2, 0, 1
另外两者的代码可以参考链接: 这篇博客(博主是听风忆雪).
// categorical_crossentropy tf_version=1.14
import tensorflow as tf
input_data=tf.Variable([[0.2,0.1,0.9], [0.3,0.4,0.6]], dtype=tf.float32)
output=tf.nn.softmax_cross_entropy_with_logits_v2(logits=input_data, labels=[[1,0,0],[0,1,0]])
with tf.Session() as sess:
init=tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))
#[1.365732 1.1398311]
// sparse_categorical_crossentropy
input_data = tf.Variable([[0.2, 0.1, 0.9], [0.3, 0.4, 0.6]], dtype=tf.float32)
output = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=input_data, labels=[0, 1])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))
#[1.365732 1.1398311]
3.全连接神经网络预测房价(回归问题)
预测的房价为连续值,因此该问题属于回归问题
(1)数据集来源:keras.datasets中boston_housing数据集。其中每个样本包含13个特征,1个真实值
(2)算法的具体流程及代码实现:
- 加载数据并划分训练集、测试集、验证集
- 将数据进行归一化
- 搭建神经网络模型
- 训练神经网络模型
- 保存模型
- 测试模型的效果
//================导入相应库文件===============
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.datasets import boston_housing
from keras.layers import Dense, Dropout
from keras.utils import multi_gpu_model
from keras import regularizers # 正则化
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.utils import plot_model
from keras.models import load_model
//===============加载数据(本次未手动划分数据集)======================
#1.加载数据
(x_train, y_train), (x_valid, y_valid) = boston_housing.load_data() # 加载数据
# 转成DataFrame格式方便数据处理
x_train_pd = pd.DataFrame(x_train)
y_train_pd = pd.DataFrame(y_train)
x_valid_pd = pd.DataFrame(x_valid)
y_valid_pd = pd.DataFrame(y_valid)
print(x_train_pd.head(5))
print('-------------------')
print(y_train_pd.head(5))
//===============数据归一化(预处理部分)======================
print("数据归一化")
#2.数据归一化
#训练集归一化
min_max_scaler = MinMaxScaler()
min_max_scaler.fit(x_train_pd)
x_train = min_max_scaler.transform(x_train_pd)
min_max_scaler.fit(y_train_pd)
y_train = min_max_scaler.transform(y_train_pd)
#验证集归一化
min_max_scaler.fit(x_valid_pd)
x_valid = min_max_scaler.transform(x_valid_pd)
min_max_scaler.fit(y_valid_pd)
y_valid = min_max_scaler.transform(y_valid_pd)
print("2.构建模型并训练模型:")
#3.训练模型
//==============搭建神经网络模型======================
model = Sequential()
model.add(Dense(units= 10,
activation='relu',
input_shape=(x_train_pd.shape[1],)
))
model.add(Dropout(0.2))
model.add(Dense(units=15,
kernel_regularizer=regularizers.l2(0.01),
activity_regularizer=regularizers.l1(0.01),
activation= 'relu'
))
model.add(Dense(units=1,
activation='linear'))
print(model.summary())#打印模型结构
//===============训练神经网络模型======================
print("2.训练模型:")
model.compile(loss='mse',
optimizer='adam')
history = model.fit(x_train, y_train,
epochs=200, # 迭代次数
batch_size=200, # 每次用来梯度下降的批处理数据大小
verbose=2, # verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:输出训练进度,2:输出每一个epoch
validation_data = (x_valid, y_valid) # 验证集
)
if __name__ == "__main__":
//===============结果可视化======================
print('结果可视化:')
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
//===============保存模型======================
model.save('model_MLP.h5') # creates a HDF5 file 'my_model.h5'
# 模型可视化 pip install pydot
plot_model(model, to_file='model_MLP.png', show_shapes=True)
# 加载模型
model = load_model('model_MLP.h5')
//===============测试模型======================
print('3.预测模型')
y_new = model.predict(x_valid)
min_max_scaler.fit(y_valid_pd)
y_new = min_max_scaler.transform(y_new)
(3)代码输出结果:
- model.summary
- 训练过程及可视化
可视化过程
- 模型可视化
在这个过程中可能会出现**FileNotFoundError: [WinError 2] “dot” not found in path.**的问题,是因为未安装pydot库,同时还需要注意安装相应的软件,解决方法可以参照这篇博客.
结果如下: