神经网络Softmax层 Python实现

                                            Softmax Python实现

一 、不使用one-hot编码

import numpy as np

def data_loss_softmax(scores, labels):
    num_examples = scores.shape[0]
    exp_scores = np.exp(scores)
    exp_scores_sum = np.sum(exp_scores, axis=1)

    correct_probs = exp_scores[range(num_examples), labels] / exp_scores_sum
    correct_probs = -np.log(correct_probs)
    data_loss = np.sum(correct_probs) / num_examples
    return data_loss


data=np.array([[0.6,0.2,0.01],[0,0,1],[0.02,0.9,0.3]])
print(data)
labels=np.array([0,2,1])
print(data_loss_softmax(data,labels))

 1 【data】 3*3 每行一个样本,列代表神经网络最后一层的分类值大小,维度为3

[[0.6  0.2  0.01]
 [0.   0.   1.  ]
 [0.02 0.9  0.3 ]]

 2【label】 代表真实的类别 0 1 2代表分类号,这里不使用one-hot编码

   [0,2,1]

3  num_examples = scores.shape[0]
   exp_scores = np.exp(scores)

   对矩阵exp_scores 每一个取指数 exp()

[[1.8221188  1.22140276 1.01005017]
 [1.         1.         2.71828183]
 [1.02020134 2.45960311 1.34985881]]


4 exp_scores_sum = np.sum(exp_scores, axis=1)

 对每一行计算和,注意axis=1 代表在第二个轴上计算和这样第二轴的维度计算完毕后就会变为1

[4.05357173 4.71828183 4.82966326]

 5   correct_probs = exp_scores[range(num_examples), labels] / exp_scores_sum

     注意此处取出了每个样本(每行)对应的真实类别号位置的值,这也是为何没有使用one-hot编码

  的原因

注意 exp_scores[range(num_examples), labels]和  exp_scores[:, labels]的区别  exp_scores[range(num_examples), labels]计算获得是3*1的维度,而  exp_scores[:, labels]获得的还是3*3 的维度,使用exp_scores[range(num_examples), labels]可以获得每一行特定列位置的数值

[0.44950945 0.57611688 0.5092701 ]

6计算softmax值 

    由于此处correct_probs取出的输出是对应真实类别位置的值,值越大 计算-np.log(correct_probs)结果越小,代表输出的类别正确
      correct_probs = -np.log(correct_probs)

   [0.7995984  0.55144471 0.67477675]

7 计算平均损失
      data_loss = np.sum(correct_probs) / num_examples

      0.67

二、使用onehot编码

def data_loss_softmax_onehot(scores, labels):
    num_examples = scores.shape[0]
    exp_scores = np.exp(scores)
    #print(exp_scores)
    exp_scores_sum = np.sum(exp_scores, axis=1)
    #print(exp_scores_sum)
    correct_probs = exp_scores[:] / exp_scores_sum
    #print(correct_probs)
    correct_probs2 = -labels*np.log(correct_probs)
    #print(correct_probs2)
    data_loss = np.sum(correct_probs2) / num_examples

    return data_loss


data=np.array([[0.6,0.2,0.01],[0,0,1],[0.02,0.9,0.3]])
# print(data)
labels=np.array([[1,0,0],[0,0,1],[0,1,0]])

print(data_loss_softmax_onehot(data, labels))

输出
--exp_scores 
[[1.8221188  1.22140276 1.01005017]
 [1.         1.         2.71828183]
 [1.02020134 2.45960311 1.34985881]]

--exp_scores_sum 
[4.05357173 4.71828183 4.82966326]

--correct_probs
[[0.44950945 0.258866   0.2091347 ]
 [0.24669602 0.21194156 0.56283051]
 [0.25167961 0.52129211 0.27949336]]

--correct_probs2 
[[ 0.7995984  -0.         -0.        ]
 [-0.         -0.          0.57477675]
 [-0.          0.65144471 -0.        ]]
--最后整个矩阵求和取平均
0.6752732868378

代码不同的地方是

 correct_probs = exp_scores[:] / exp_scores_sum
 correct_probs = -labels*np.log(correct_probs)

此处使用的是数组*数组  

[1,0,0]*[0.44950945 0.258866   0.2091347 ]=[0.7995984  -0.         -0.        ]

上一篇:modelmapper 简单只能的对象映射工具


下一篇:cf228 div2 B. Fox and Cross ( 贪心, 模拟)