void init_tensorflow(void) { tf_tensor_tag = scm_make_smob_type("tensor", sizeof(struct tf_tensor_t)); scm_set_smob_free(tf_tensor_tag, free_tensor); tf_graph_tag = scm_make_smob_type("graph", sizeof(struct tf_graph_t)); scm_set_smob_free(tf_graph_tag, free_graph); tf_description_tag = scm_make_smob_type("description", sizeof(struct tf_description_t)); scm_set_smob_free(tf_description_tag, free_description); tf_output_tag = scm_make_smob_type("output", sizeof(struct tf_output_t)); scm_set_smob_free(tf_output_tag, free_output); tf_session_tag = scm_make_smob_type("session", sizeof(struct tf_session_t)); scm_set_smob_free(tf_session_tag, free_session); _status = TF_NewStatus(); scm_c_define("TF_FLOAT" , scm_from_int(TF_FLOAT )); scm_c_define("TF_DOUBLE" , scm_from_int(TF_DOUBLE )); scm_c_define("TF_UINT8" , scm_from_int(TF_UINT8 )); scm_c_define("TF_INT8" , scm_from_int(TF_INT8 )); scm_c_define("TF_UINT16" , scm_from_int(TF_UINT16 )); scm_c_define("TF_INT16" , scm_from_int(TF_INT16 )); scm_c_define("TF_UINT32" , scm_from_int(TF_UINT32 )); scm_c_define("TF_INT32" , scm_from_int(TF_INT32 )); scm_c_define("TF_UINT64" , scm_from_int(TF_UINT64 )); scm_c_define("TF_COMPLEX64" , scm_from_int(TF_COMPLEX64 )); scm_c_define("TF_INT64" , scm_from_int(TF_INT64 )); scm_c_define("TF_BOOL" , scm_from_int(TF_BOOL )); scm_c_define("TF_COMPLEX128", scm_from_int(TF_COMPLEX128)); scm_c_define("TF_STRING" , scm_from_int(TF_STRING )); scm_c_define_gsubr("make-tensor" , 4, 0, 0, SCM_FUNC(make_tensor )); scm_c_define_gsubr("tf-from-tensor" , 1, 0, 0, SCM_FUNC(tf_from_tensor )); scm_c_define_gsubr("make-graph" , 0, 0, 0, SCM_FUNC(make_graph )); scm_c_define_gsubr("tf-graph-export_" , 2, 0, 0, SCM_FUNC(tf_graph_export_ )); scm_c_define_gsubr("tf-graph-import_" , 2, 0, 0, SCM_FUNC(tf_graph_import_ )); scm_c_define_gsubr("make-description" , 3, 0, 0, SCM_FUNC(make_description )); scm_c_define_gsubr("tf-finish-operation" , 2, 0, 0, SCM_FUNC(tf_finish_operation )); scm_c_define_gsubr("tf-add-input" , 2, 0, 0, SCM_FUNC(tf_add_input )); scm_c_define_gsubr("tf-add-input-list" , 2, 0, 0, SCM_FUNC(tf_add_input_list )); scm_c_define_gsubr("tf-set-attr-string" , 3, 0, 0, SCM_FUNC(tf_set_attr_string )); scm_c_define_gsubr("tf-set-attr-int" , 3, 0, 0, SCM_FUNC(tf_set_attr_int )); scm_c_define_gsubr("tf-set-attr-int-list" , 3, 0, 0, SCM_FUNC(tf_set_attr_int_list )); scm_c_define_gsubr("tf-set-attr-bool" , 3, 0, 0, SCM_FUNC(tf_set_attr_bool )); scm_c_define_gsubr("tf-set-attr-float" , 3, 0, 0, SCM_FUNC(tf_set_attr_float )); scm_c_define_gsubr("tf-set-attr-float-list" , 3, 0, 0, SCM_FUNC(tf_set_attr_float_list )); scm_c_define_gsubr("tf-set-attr-type" , 3, 0, 0, SCM_FUNC(tf_set_attr_type )); scm_c_define_gsubr("tf-set-attr-shape" , 3, 0, 0, SCM_FUNC(tf_set_attr_shape )); scm_c_define_gsubr("tf-set-attr-tensor" , 3, 0, 0, SCM_FUNC(tf_set_attr_tensor )); scm_c_define_gsubr("make-tf-session" , 1, 0, 0, SCM_FUNC(make_tf_session )); scm_c_define_gsubr("tf-run" , 3, 0, 0, SCM_FUNC(tf_run )); scm_c_define_gsubr("tf-add-gradient_" , 3, 0, 0, SCM_FUNC(tf_add_gradient_ )); scm_c_define_gsubr("tf-output?" , 1, 0, 0, SCM_FUNC(tf_outputq )); scm_c_define_gsubr("tf-graph-operation-by-name_" , 2, 0, 0, SCM_FUNC(tf_graph_operation_by_name_)); scm_c_define_gsubr("tf-operation-names_" , 1, 0, 0, SCM_FUNC(tf_operation_names_ )); }
DNNModel *ff_dnn_load_model_tf(const char *model_filename) { DNNModel *model = NULL; TFModel *tf_model = NULL; TF_Buffer *graph_def; TF_ImportGraphDefOptions *graph_opts; model = av_malloc(sizeof(DNNModel)); if (!model){ return NULL; } tf_model = av_malloc(sizeof(TFModel)); if (!tf_model){ av_freep(&model); return NULL; } tf_model->session = NULL; tf_model->input_tensor = NULL; tf_model->output_data = NULL; graph_def = read_graph(model_filename); if (!graph_def){ av_freep(&tf_model); av_freep(&model); return NULL; } tf_model->graph = TF_NewGraph(); tf_model->status = TF_NewStatus(); graph_opts = TF_NewImportGraphDefOptions(); TF_GraphImportGraphDef(tf_model->graph, graph_def, graph_opts, tf_model->status); TF_DeleteImportGraphDefOptions(graph_opts); TF_DeleteBuffer(graph_def); if (TF_GetCode(tf_model->status) != TF_OK){ TF_DeleteGraph(tf_model->graph); TF_DeleteStatus(tf_model->status); av_freep(&tf_model); av_freep(&model); return NULL; } model->model = (void *)tf_model; model->set_input_output = &set_input_output_tf; return model; }
static DNNReturnType load_tf_model(TFModel *tf_model, const char *model_filename) { TF_Buffer *graph_def; TF_ImportGraphDefOptions *graph_opts; graph_def = read_graph(model_filename); if (!graph_def){ return DNN_ERROR; } tf_model->graph = TF_NewGraph(); tf_model->status = TF_NewStatus(); graph_opts = TF_NewImportGraphDefOptions(); TF_GraphImportGraphDef(tf_model->graph, graph_def, graph_opts, tf_model->status); TF_DeleteImportGraphDefOptions(graph_opts); TF_DeleteBuffer(graph_def); if (TF_GetCode(tf_model->status) != TF_OK){ TF_DeleteGraph(tf_model->graph); TF_DeleteStatus(tf_model->status); return DNN_ERROR; } return DNN_SUCCESS; }
DNNModel *ff_dnn_load_default_model_tf(DNNDefaultModel model_type) { DNNModel *model = NULL; TFModel *tf_model = NULL; TF_OperationDescription *op_desc; TF_Operation *op; TF_Output input; static const int64_t input_shape[] = {1, -1, -1, 1}; static const char tanh[] = "Tanh"; static const char sigmoid[] = "Sigmoid"; static const char relu[] = "Relu"; static const float *srcnn_consts[] = { srcnn_conv1_kernel, srcnn_conv1_bias, srcnn_conv2_kernel, srcnn_conv2_bias, srcnn_conv3_kernel, srcnn_conv3_bias }; static const long int *srcnn_consts_dims[] = { srcnn_conv1_kernel_dims, srcnn_conv1_bias_dims, srcnn_conv2_kernel_dims, srcnn_conv2_bias_dims, srcnn_conv3_kernel_dims, srcnn_conv3_bias_dims }; static const int srcnn_consts_dims_len[] = { 4, 1, 4, 1, 4, 1 }; static const char *srcnn_activations[] = { relu, relu, relu }; static const float *espcn_consts[] = { espcn_conv1_kernel, espcn_conv1_bias, espcn_conv2_kernel, espcn_conv2_bias, espcn_conv3_kernel, espcn_conv3_bias }; static const long int *espcn_consts_dims[] = { espcn_conv1_kernel_dims, espcn_conv1_bias_dims, espcn_conv2_kernel_dims, espcn_conv2_bias_dims, espcn_conv3_kernel_dims, espcn_conv3_bias_dims }; static const int espcn_consts_dims_len[] = { 4, 1, 4, 1, 4, 1 }; static const char *espcn_activations[] = { tanh, tanh, sigmoid }; input.index = 0; model = av_malloc(sizeof(DNNModel)); if (!model){ return NULL; } tf_model = av_malloc(sizeof(TFModel)); if (!tf_model){ av_freep(&model); return NULL; } tf_model->session = NULL; tf_model->input_tensor = NULL; tf_model->output_data = NULL; tf_model->graph = TF_NewGraph(); tf_model->status = TF_NewStatus(); #define CLEANUP_ON_ERROR(tf_model, model) { \ TF_DeleteGraph(tf_model->graph); \ TF_DeleteStatus(tf_model->status); \ av_freep(&tf_model); \ av_freep(&model); \ return NULL; \ } op_desc = TF_NewOperation(tf_model->graph, "Placeholder", "x"); TF_SetAttrType(op_desc, "dtype", TF_FLOAT); TF_SetAttrShape(op_desc, "shape", input_shape, 4); op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ CLEANUP_ON_ERROR(tf_model, model); } switch (model_type){ case DNN_SRCNN: op = add_pad_op(tf_model, op, 6); if (!op){ CLEANUP_ON_ERROR(tf_model, model); } op = add_conv_layers(tf_model, srcnn_consts, srcnn_consts_dims, srcnn_consts_dims_len, srcnn_activations, op, 3); if (!op){ CLEANUP_ON_ERROR(tf_model, model); } break; case DNN_ESPCN: op = add_pad_op(tf_model, op, 4); if (!op){ CLEANUP_ON_ERROR(tf_model, model); } op = add_conv_layers(tf_model, espcn_consts, espcn_consts_dims, espcn_consts_dims_len, espcn_activations, op, 3); if (!op){ CLEANUP_ON_ERROR(tf_model, model); } op_desc = TF_NewOperation(tf_model->graph, "DepthToSpace", "depth_to_space"); input.oper = op; TF_AddInput(op_desc, input); TF_SetAttrType(op_desc, "T", TF_FLOAT); TF_SetAttrInt(op_desc, "block_size", 2); op = TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ CLEANUP_ON_ERROR(tf_model, model); } break; default: CLEANUP_ON_ERROR(tf_model, model); } op_desc = TF_NewOperation(tf_model->graph, "Identity", "y"); input.oper = op; TF_AddInput(op_desc, input); TF_FinishOperation(op_desc, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ CLEANUP_ON_ERROR(tf_model, model); } model->model = (void *)tf_model; model->set_input_output = &set_input_output_tf; return model; }