大致是跟着 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
![]() | 1 towser 2021-07-02 07:11:41 +08:00 很酷 |
2 cclin 2021-07-02 08:03:08 +08:00 via Android 学习一下,今天的摸鱼材料有了 |
![]() | 3 shm7 2021-07-02 12:55:41 +08:00 via iPhone 为啥不按照 torch 写 sess 这种有毛病不能调的痛 |
![]() | 5 leimao 2021-07-03 02:29:03 +08:00 header-only 是痛处,应该去掉。 |
![]() | 6 c0xt30a OP @leimao 为什么是痛处?我为了让它脱离二进制依赖特意花了功夫特意这么设计的。而且还把 computation graph 做成了编译时的。 |
![]() | 7 275761919 2021-07-07 09:45:19 +08:00 太秀了 |