Softmax多分类
简介
神经网络的原始输出不是一个概率值,实际上只是对输入数据做一个加权以及非线性处理,如果我们想要对输出的数据进行分类处理的话就需要加入一个激活函数使得每个输出的类别进行比例化,而且要求所有分类的概率之和为1。
在对数几率回归介绍了有关二分类的问题,如果对于多分类的话我们还是使用sigmoid激活函数的话无法达到目的,而Softmax函数又叫归一化指数函数,是对有限项离散概率分布的梯度对数归一化的处理函数。
1.多分类激活函数Softmax函数
a.Softmax函数要求每个样本必须属于某个类别,且所有可能的样本均被覆盖;
b.当只有两个类别的时候Softmax函数与对数几率回归完全相同。
2.损失函数
其中 K: 类别的数量 y:是否是类别c, , p: 样本属于类别c的概率
交叉熵损失函数经常会被用在分类问题中,特别是神经网络分类问题中,由于交叉熵涉及到每个类别的概率,所以在神经网络中,交叉熵与softmax函数经常配合使用
下面使用tensorflow1.14.0来个实例
1.引入数据
import requests
import numpy as np
import tensorflow as tf
import pandas as pd
r = requests.get('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data')
with open('iris.data', 'w') as f:
f.write(r.text)
data = pd.read_csv('./iris.data', names=['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width', 'Species'])
2.数据处理
data.Species.unique()
data['c1'] = np.array(data['Species']=='Iris-setosa').astype(np.float32)
data['c2'] = np.array(data['Species']=='Iris-versicolor').astype(np.float32)
data['c3'] = np.array(data['Species']=='Iris-virginica').astype(np.float32)
del data['Species']
target = np.stack([data.c1.values, data.c2.values, data.c3.values]).T
data_X = np.stack([data.Sepal_Length.values, data.Sepal_Width.values, data.Petal_Length.values, data.Petal_Width.values]).T
3.建模
x = tf.placeholder('float', shape=(None, 4))
y = tf.placeholder('float', shape=(None, 3))
weight = tf.Variable(tf.truncated_normal([4,3]))
bias = tf.Variable(tf.truncated_normal([3]))
combine_input = tf.matmul(x,weight)+bias
pred = tf.nn.softmax(combine_input)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=combine_input))
correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
train_step = tf.train.AdamOptimizer(0.0005).minimize(loss)
3.训练
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for i in range(10000):
index = np.random.permutation(len(target))
data_X = data_X[index]
target = target[index]
sess.run(train_step, feed_dict={x: data_X, y:target})
if i % 1000 == 0:
print(sess.run((loss, accuracy), feed_dict={x: data_X, y:target}))
最后看结果
训练结果下面用tensorflow 2.0来实现同样的结果
第一种方法的数据的获取都是完全一样的
a.数据处理
labels = data.Species.unique()
class_labels = dict((name,index) for index, name in enumerate(labels))
class_list = [class_labels[name] for name in list(data.Species)]
target = np.array(class_list)
data_X = data.iloc[:,0:-1]
b.建模
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(128, input_shape=(4,), activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(32, activation='relu'))
model.add(tf.keras.layers.Dense(16, activation='relu'))
model.add(tf.keras.layers.Dense(3, activation='softmax'))
c.编译
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['acc'])
d.训练
history = model.fit(data_X, target, epochs=200)
最后我们来看结果