您的位置:首页 > 其它

从零开始编写深度学习库(一)SoftmaxWithLoss CPU编写

2017-05-11 11:15 399 查看
从零开始编写深度学习库(一)SoftmaxWithLoss CPU编写
博客http://blog.csdn.net/hjimce
微博黄锦池-hjimce   qq:1393852684
一、C++实现
void softmax_function(const Eigen::MatrixXf &inputs,Eigen::MatrixXf &softmax) {
softmax = inputs.array().exp();
Eigen::VectorXf sorfmax_rowsum = softmax.rowwise().sum();
softmax = softmax.array().colwise() / sorfmax_rowsum.array();//行归一化
}
//假设前一层网络经过全连接input=wx+b后,经过soft损失函数求导:sotfmax_net-pro_real
//https://math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function
void softmax_loss_forward_backward(const Eigen::MatrixXf &inputs,const Eigen::VectorXf &label, Eigen::MatrixXf &d_inputs,float &loss) {

Eigen::MatrixXf softmax;
softmax_function(inputs, softmax);

Eigen::MatrixXf real_label = Eigen::MatrixXf::Zero(softmax.rows(), softmax.cols());
assert(label.rows() == inputs.rows());
for (int i=0;i<label.rows();i++)
{
real_label(i, label(i)) = 1;
}

loss=-(real_label.array()*softmax.array().log()).mean();//交叉熵损失函数平均值
d_inputs = (softmax - real_label)/(inputs.rows()*inputs.cols());//由于loss计算的时候,我们一般是计算loss mean,所以反向求导的时候,需要除以(inputs.rows()*inputs.cols())

}

int main()
{
int batch_size = 4;
int input_size = 3;
int output_size = 2;
Eigen::MatrixXf inputs(batch_size, input_size);
inputs << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
Eigen::VectorXf label(batch_size);
label << 1, 0, 1, 1;

Eigen::MatrixXf d_inputs;
float loss;
softmax_loss_forward_backward(inputs, label,d_inputs,loss);
std::cout << loss << std::endl;
std::cout << d_inputs << std::endl;

return 0;
}

二、tensorflow验证以上代码是否正确
import tensorflow as tf
inputs=tf.constant([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=tf.float32)
label=tf.constant([1,0,1,1])
one_hot=tf.one_hot(label,3)
predicts=tf.nn.softmax(inputs)
loss =-tf.reduce_mean(one_hot * tf.log(predicts))
gradient=tf.gradients(loss,inputs)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer());
print (sess.run(gradient))

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: