大致是跟着 tensorflow 1 的流程走了一遍,用 variable, placeholder, operator, constant 来建立一个编译时计算图。正向传播时候从全局拉出一个 session,把 placeholder 绑定到 tensor 上就可以开始了。正向传播完了之后再反向传播一遍所有 variable 的梯度也就出来了。然后用个 optimizer 来更新所有的 variable 一遍就是训练了一次。
起初只是为了练手,大多数算子写的都是很暴露,少有间接层,几乎所有的细节都可以就地找到,代码也很简洁。后来发现这东西只是拿来自娱自乐意思不大,就尽量往 kera 的 api 上靠,希望能够引起注意。
目前还是非常 tiny,能做一些简单的 classification 和 GAN 的训练。典型的 classification 代码大致如下:
#include "../include/ceras.hpp"
#include <iostream>
int main()
{
using namespace ceras;
random_generator.seed( 42 );
auto input = Input(); // shape( 28, 28 )
auto l0 = Reshape({28*28,})( input );
auto l1 = ReLU( Dense( 512, 28*28 )( l0 ) );
auto l2 = ReLU( Dense( 256, 512 )( l1 ) );
auto output = Dense( 10, 256 )( l2 );
auto m = model( input, output );
m.summary( "./mnist_minimal.dot" );
std::size_t const batch_size = 10;
float learning_rate = 0.005f;
auto cm = m.compile( CategoricalCrossentropy(), SGD(batch_size, learning_rate) );
unsigned long epoches = 50;
int verbose = 1;
double validation_split = 0.1;
auto const& [x_training, y_training, x_test, y_test] = dataset::mnist::load_data();
auto history = cm.fit( x_training.as_type<float>()/255.0f, y_training.as_type<float>(), batch_size, epoches, verbose, validation_split );
auto error = cm.evaluate( x_test.as_type<float>()/255.0, y_test.as_type<float>(), batch_size );
std::cout << "\nPrediction error on the test set is " << error << std::endl;
return 0;
}
希望能有人讨论,代码在这里: https://github.com/fengwang/ceras
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.