forked from chenzomi12/AISystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path02.srt
1536 lines (1152 loc) · 26.8 KB
/
02.srt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1
00:00:00,000 --> 00:00:03,823
字幕生成:qiaokai 字幕校对:A是传奇
2
00:00:05,350 --> 00:00:07,560
Hello,大家好,我是ZOMI
3
00:00:07,560 --> 00:00:12,080
这里面ZOMI两个英文单词都是大写
4
00:00:12,080 --> 00:00:15,240
因为它是我中文名字的一个缩写
5
00:00:15,240 --> 00:00:20,600
今天我要给大家汇报的还是模型转换和优化这个内容里面
6
00:00:20,600 --> 00:00:23,480
在模型转换技术这个内容里面
7
00:00:23,480 --> 00:00:26,200
后面的更新频率应该会越来越慢
8
00:00:26,200 --> 00:00:27,200
因为很多知识
9
00:00:27,680 --> 00:00:29,627
其实在网上很难搜得到
10
00:00:29,627 --> 00:00:31,627
更多的是工程化的一些经验的总结
11
00:00:33,720 --> 00:00:36,880
这里面应该会分开两个视频给大家介绍的
12
00:00:36,880 --> 00:00:39,840
可以看一下主要有很多内容
13
00:00:40,400 --> 00:00:44,880
首先在第一个视频更多的是聚焦于一些工程理念和知识概念
14
00:00:44,880 --> 00:00:46,480
例如模型转换的挑战
15
00:00:46,480 --> 00:00:49,000
还有整体的架构应该长什么样子
16
00:00:49,000 --> 00:00:54,640
接着去看一看模型的序列化和反序列化的操作
17
00:00:54,800 --> 00:00:58,120
序列化的工作就是把其他AI框架的网络模型
18
00:00:58,120 --> 00:01:00,480
转换成为推进行的模型
19
00:01:01,240 --> 00:01:04,520
反序列化就是把已经保存下来的网络模型
20
00:01:04,520 --> 00:01:08,000
加载到内存当中给推进行去执行的
21
00:01:08,000 --> 00:01:11,360
接着会去介绍序列化和反序列化当中
22
00:01:11,360 --> 00:01:13,600
用的很多的两种格式
23
00:01:13,600 --> 00:01:15,440
一种是protobuffer
24
00:01:15,440 --> 00:01:17,280
一种是flatbuffer
25
00:01:17,280 --> 00:01:18,600
讲完这两个内容之后
26
00:01:18,840 --> 00:01:20,800
将会在下个内容里面
27
00:01:20,800 --> 00:01:24,480
来到一些比较内核的技术或者内核的内容
28
00:01:24,520 --> 00:01:27,000
就是自定义计算图的IR
29
00:01:27,000 --> 00:01:30,840
针对推力引擎的计算图的IR应该怎么定义
30
00:01:31,360 --> 00:01:34,040
然后第二个内容也是很重要的一块
31
00:01:34,040 --> 00:01:37,000
转换的流程和技术的细节
32
00:01:37,000 --> 00:01:40,440
流程和细节这个就是指导怎么去开发
33
00:01:40,440 --> 00:01:41,680
怎么去写代码的
34
00:01:43,520 --> 00:01:45,720
下面来到第一个正式的内容
35
00:01:45,720 --> 00:01:48,160
转换模块的挑战和架构
36
00:01:48,160 --> 00:01:49,440
其实挑战和架构
37
00:01:49,440 --> 00:01:53,360
在上一节里面已经详细的去给大家去汇报过
38
00:01:53,400 --> 00:01:55,640
今天简单的去罗列一下
39
00:01:56,800 --> 00:01:59,720
Converter这个模块其实有非常多的挑战
40
00:01:59,720 --> 00:02:03,640
第一个就是AI框架或者AI本身有非常多的模型
41
00:02:03,640 --> 00:02:05,720
而且有非常多的框架
42
00:02:05,720 --> 00:02:07,880
不同的框架有不同的知识格式
43
00:02:07,880 --> 00:02:10,920
而且需要支持非常多主流的网络模型
44
00:02:10,920 --> 00:02:12,560
AI发展的越来越多
45
00:02:12,560 --> 00:02:15,080
很多模型都是千奇百怪
46
00:02:15,080 --> 00:02:18,720
最后就是需要支持很多AI特有的一些特性
47
00:02:19,840 --> 00:02:21,560
为了应对上面的这些挑战
48
00:02:21,720 --> 00:02:24,720
所以设计了一个转换模块的整体的架构
49
00:02:24,720 --> 00:02:26,640
主要是由Graph Converter
50
00:02:26,640 --> 00:02:29,760
还有Graph Optimizer两个模块来去组成
51
00:02:29,760 --> 00:02:32,360
今天主要是围绕着Graph Converter
52
00:02:32,360 --> 00:02:35,240
就是图转换的模块
53
00:02:35,240 --> 00:02:36,640
下面可以看一下
54
00:02:36,640 --> 00:02:40,040
主要就是聚焦于上面的这坨内容
55
00:02:40,040 --> 00:02:42,760
每一个AI框架都会有自己的一个Converter
56
00:02:42,760 --> 00:02:46,960
最终都会汇聚成自己推理引擎的IR
57
00:02:48,040 --> 00:02:49,720
既然IR很重要
58
00:02:49,720 --> 00:02:52,640
看一下整个转换模块的工作流程当中
59
00:02:52,640 --> 00:02:55,640
可以看到左边的很多的不同的框架
60
00:02:55,640 --> 00:02:58,720
最后都会汇聚成自己的一个独立的IR
61
00:02:59,160 --> 00:03:00,680
转换模块的阶段
62
00:03:00,920 --> 00:03:03,680
统一了整个计算图的IR
63
00:03:03,880 --> 00:03:05,560
于是在优化模块的时候
64
00:03:05,560 --> 00:03:08,120
就可以通过统一的自定义的IR
65
00:03:08,120 --> 00:03:11,080
完成很多不同的计算图的优化的模式
66
00:03:11,080 --> 00:03:12,280
或者优化图的Path
67
00:03:12,280 --> 00:03:15,000
这个就是为什么需要自定义的IR
68
00:03:15,000 --> 00:03:17,560
为什么需要深入的去给大家讲解
69
00:03:17,560 --> 00:03:19,520
转换模块的作用
70
00:03:20,320 --> 00:03:22,760
下面来看一下第二个比较重要的内容
71
00:03:22,760 --> 00:03:26,200
就是模型的序列化和反序列化
72
00:03:26,440 --> 00:03:29,360
首先来了解一下模型的序列化的工作
73
00:03:29,600 --> 00:03:31,480
其实序列化很简单
74
00:03:32,240 --> 00:03:34,360
把模型在部署的时候
75
00:03:34,360 --> 00:03:36,320
怎么去把已经训练好的模型
76
00:03:36,320 --> 00:03:38,400
AI框架训练出来的模型
77
00:03:38,400 --> 00:03:40,480
把它存储起来
78
00:03:40,480 --> 00:03:42,280
给后续需要Fine Tuning
79
00:03:42,280 --> 00:03:44,000
或者推理的时候使用的
80
00:03:44,000 --> 00:03:47,240
而反序列化就是把刚才保存下来的
81
00:03:47,240 --> 00:03:49,320
网络模型的结构还有权重
82
00:03:49,800 --> 00:03:51,800
反序列到内存当中
83
00:03:51,800 --> 00:03:54,080
内存就变成一个具体的对象
84
00:03:54,080 --> 00:03:56,880
看一下下面的图
85
00:03:57,880 --> 00:03:59,280
在AI框架执行阶段
86
00:03:59,400 --> 00:04:01,480
写的很多网络模型的代码
87
00:04:01,480 --> 00:04:02,920
还有一些权重参数
88
00:04:03,040 --> 00:04:06,120
其实都变成内存的一个对象
89
00:04:06,120 --> 00:04:07,360
需要保存下来
90
00:04:07,360 --> 00:04:08,160
把权重
91
00:04:08,160 --> 00:04:09,600
把代码固化下来
92
00:04:09,600 --> 00:04:12,520
变成硬盘的一些具体的地址
93
00:04:12,880 --> 00:04:14,000
最后要加载的时候
94
00:04:14,160 --> 00:04:16,080
就变成需要反序列化
95
00:04:16,080 --> 00:04:17,640
回去内存对象
96
00:04:17,880 --> 00:04:19,800
这个就是一般的AI框架里面
97
00:04:19,800 --> 00:04:22,080
所使用的一个流程
98
00:04:23,960 --> 00:04:25,920
而在推理引擎也是相同的
99
00:04:25,920 --> 00:04:28,640
左边就是AI框架训练的一个网络模型
100
00:04:28,640 --> 00:04:29,880
把它序列化
101
00:04:29,880 --> 00:04:32,000
需要用推理引擎的序列化的API
102
00:04:32,000 --> 00:04:32,960
把它固化下来
103
00:04:32,960 --> 00:04:34,760
成为硬盘的数据
104
00:04:35,040 --> 00:04:36,680
在真正推理引擎执行的时候
105
00:04:36,800 --> 00:04:38,080
需要把一些数据
106
00:04:38,080 --> 00:04:39,880
反序列化成为内存的对象
107
00:04:40,080 --> 00:04:41,280
最后再去执行
108
00:04:41,280 --> 00:04:42,880
这个就是整体的流程
109
00:04:45,808 --> 00:04:48,048
下面来看一下序列化的分类
110
00:04:48,640 --> 00:04:50,800
实际上序列化的格式有很多种
111
00:04:50,800 --> 00:04:51,400
有XML
112
00:04:51,600 --> 00:04:51,920
JSON
113
00:04:52,120 --> 00:04:54,120
还有Protobuffer和flatbuffer
114
00:04:55,115 --> 00:04:58,115
而在AI框架或者AI的领域里面
115
00:04:58,115 --> 00:05:00,649
Protobuffer是用的最为广泛的
116
00:05:00,731 --> 00:05:02,211
可以看到下面这个图
117
00:05:02,460 --> 00:05:05,013
谷歌是protobuffer的一个发起者
118
00:05:05,171 --> 00:05:07,491
最后现在经常用的onix
119
00:05:07,957 --> 00:05:10,113
是Facebook和微软组成一个联盟
120
00:05:10,113 --> 00:05:12,233
一起去支持这种开放性的格式
121
00:05:13,035 --> 00:05:13,755
而另外一方面
122
00:05:13,755 --> 00:05:15,635
平时用的苹果很多AI功能
123
00:05:15,635 --> 00:05:18,035
包括Siri用的就是CoreML的格式
124
00:05:18,035 --> 00:05:20,155
而CoreML也是继承于Protobuffer
125
00:05:20,155 --> 00:05:21,675
进行自己一个魔改
126
00:05:21,675 --> 00:05:23,635
或者自己的一个修改定义的
127
00:05:25,492 --> 00:05:27,252
下面以一个简单的例子
128
00:05:27,252 --> 00:05:29,852
去看一下Pytorch的序列化的方式
129
00:05:30,372 --> 00:05:31,492
Pytorch的内部格式
130
00:05:31,692 --> 00:05:34,492
只是存储已经训好的网络模型的状态
131
00:05:34,492 --> 00:05:35,732
所谓的这些状态
132
00:05:35,732 --> 00:05:38,012
主要是包括权重了
133
00:05:38,012 --> 00:05:38,812
偏移了
134
00:05:38,812 --> 00:05:41,126
优化器的更新的参数
135
00:05:41,126 --> 00:05:44,486
更多的是对网络模型的权重参数信息
136
00:05:44,486 --> 00:05:46,206
进行加载和保存的
137
00:05:46,486 --> 00:05:49,086
其他参数其实也有非常的多
138
00:05:49,086 --> 00:05:50,726
只是不一一列举了
139
00:05:50,726 --> 00:05:51,406
另外的话
140
00:05:51,406 --> 00:05:52,766
像Pytorch的内部格式
141
00:05:52,966 --> 00:05:54,846
非常类似于Python里面的
142
00:05:54,846 --> 00:05:55,846
序列化的方式
143
00:05:55,846 --> 00:05:57,886
直接用pickle来去做的
144
00:05:57,886 --> 00:06:00,846
这个就是Pytorch原生的方式
145
00:06:01,000 --> 00:06:03,360
在代码里面就直接torch.save
146
00:06:03,360 --> 00:06:05,400
然后把网络模型
147
00:06:05,800 --> 00:06:06,480
告诉API
148
00:06:06,480 --> 00:06:08,720
要存在哪个地址就可以了
149
00:06:09,400 --> 00:06:10,480
下次加载的时候
150
00:06:10,600 --> 00:06:12,400
直接model.load_state_dict
151
00:06:12,400 --> 00:06:14,280
然后就可以进行一个推理
152
00:06:14,280 --> 00:06:16,480
所以用起来是比较简单的
153
00:06:17,000 --> 00:06:19,800
但是这种方式实在是太naive了
154
00:06:19,800 --> 00:06:21,320
就是非常的原始
155
00:06:21,600 --> 00:06:24,480
它只是保存了网络模型的对应的参数
156
00:06:24,480 --> 00:06:25,680
网络模型的结构
157
00:06:25,680 --> 00:06:27,560
网络模型的信息计算图
158
00:06:27,560 --> 00:06:29,160
这些信息它都没有保存
159
00:06:29,160 --> 00:06:31,080
而是通过代码来去承载
160
00:06:31,080 --> 00:06:32,360
那下面来看一下
161
00:06:32,360 --> 00:06:33,440
另外一个方面
162
00:06:33,560 --> 00:06:34,720
就是Pytorch
163
00:06:34,720 --> 00:06:36,720
另外一个序列化的方式
164
00:06:36,720 --> 00:06:37,720
ONNX
165
00:06:39,400 --> 00:06:40,800
ONNX
166
00:06:40,800 --> 00:06:43,520
大家都知道Pytorch要导到一些推理引擎
167
00:06:43,520 --> 00:06:44,480
去计算的时候
168
00:06:44,880 --> 00:06:48,200
一般都会把它转成一个ONNX的格式
169
00:06:48,200 --> 00:06:49,520
那Pytorch
170
00:06:49,520 --> 00:06:51,000
那Pytorch内部
171
00:06:51,200 --> 00:06:53,520
其实是支持ONNX的export的
172
00:06:53,520 --> 00:06:55,120
包括现在在昇腾
173
00:06:55,120 --> 00:06:57,040
去对接到Pytorch的框架
174
00:06:57,040 --> 00:07:00,360
也是通过ONNX的一个接口去实现的
175
00:07:00,360 --> 00:07:03,040
下面确实看到代码很简单
176
00:07:03,040 --> 00:07:05,920
前面的都是一些加载网络模型
177
00:07:05,920 --> 00:07:08,760
最重要的就是这条torch.onnx.export
178
00:07:08,760 --> 00:07:10,920
这条语句就告诉
179
00:07:11,120 --> 00:07:13,600
需要把Pytorch的一个网络模型
180
00:07:13,880 --> 00:07:16,560
保存为alexnet.onnx
181
00:07:16,720 --> 00:07:17,920
这里面的保存的信息
182
00:07:18,040 --> 00:07:20,240
就会比Pytorch原生要多很多
183
00:07:20,240 --> 00:07:22,240
除了网络模型的权重偏移
184
00:07:22,240 --> 00:07:23,520
还有优化器的参数
185
00:07:23,520 --> 00:07:25,680
它还会保存网络模型的结构
186
00:07:25,680 --> 00:07:27,360
每一层所使用的算子
187
00:07:27,360 --> 00:07:28,120
tensor的shape
188
00:07:28,120 --> 00:07:29,960
还有很多的额外的信息
189
00:07:29,960 --> 00:07:32,720
那这些就是Pytorch序列化的一个过程
190
00:07:36,961 --> 00:07:38,360
在最后一个内容里面
191
00:07:38,360 --> 00:07:39,800
也是比较长的一个内容
192
00:07:39,800 --> 00:07:42,800
来看一下目标文件的格式
193
00:07:42,800 --> 00:07:44,000
这里面用的更多的
194
00:07:44,000 --> 00:07:44,840
在AI领域
195
00:07:44,920 --> 00:07:47,240
更多的是Protocol Buffer和Fact Buffer
196
00:07:47,600 --> 00:07:49,880
现在来看一下protobuffer
197
00:07:49,880 --> 00:07:52,080
其实protobuffer它aka叫protobuffer
198
00:07:52,480 --> 00:07:55,080
实际上它叫做Portoco Buffer
199
00:07:55,080 --> 00:07:56,280
看一下它的logo
200
00:07:56,280 --> 00:07:57,720
五颜六色的就知道
201
00:07:57,720 --> 00:08:00,040
大部分都是像谷歌的风格
202
00:08:00,320 --> 00:08:03,400
也是谷歌发起的一个开源性的项目
203
00:08:03,400 --> 00:08:06,120
因为它确实有很多特殊的优点
204
00:08:06,120 --> 00:08:07,960
比XML还有JSON要好
205
00:08:07,960 --> 00:08:10,000
所以现在很多AI框架
206
00:08:10,000 --> 00:08:10,680
Tensorflow
207
00:08:10,680 --> 00:08:11,480
MindSpore
208
00:08:11,480 --> 00:08:13,760
Pytorch都是使用protobuffer
209
00:08:13,760 --> 00:08:16,480
作为它一个主要的导出的格式
210
00:08:18,480 --> 00:08:19,320
现在看一下
211
00:08:19,320 --> 00:08:21,640
protobuffer的一个文档的语法
212
00:08:21,640 --> 00:08:23,040
那基本的语法的规则
213
00:08:23,240 --> 00:08:24,960
下面就是一段message
214
00:08:24,960 --> 00:08:26,160
然后就告诉我
215
00:08:26,160 --> 00:08:28,240
这段message属于哪个域
216
00:08:28,280 --> 00:08:30,840
然后在这个域里面加了个花括号
217
00:08:30,840 --> 00:08:32,120
那中间的这两行
218
00:08:32,280 --> 00:08:35,080
就是具体的字段的规则或者内容
219
00:08:35,080 --> 00:08:36,400
具体的中间两行
220
00:08:36,560 --> 00:08:37,840
就是具体的内容了
221
00:08:37,840 --> 00:08:39,840
看一下每一行代表什么意思
222
00:08:40,040 --> 00:08:42,320
首先有一个字段的规则
223
00:08:42,320 --> 00:08:44,560
告诉它这个字段是属于哪个范围
224
00:08:44,560 --> 00:08:46,000
然后有个数据类型
225
00:08:46,000 --> 00:08:47,200
有个名称
226
00:08:47,200 --> 00:08:48,040
等于
227
00:08:48,040 --> 00:08:49,400
然后就有一个域值了
228
00:08:49,400 --> 00:08:50,360
等于什么
229
00:08:50,560 --> 00:08:53,400
这个就是protobuffer的一个文档的
230
00:08:53,400 --> 00:08:54,920
最主要的语法规则
231
00:08:55,880 --> 00:08:57,160
下面就是Caffe
232
00:08:57,160 --> 00:09:00,040
这个AI框架用protobuffer去表示的
233
00:09:00,040 --> 00:09:02,520
那这里面有一个Data Layer
234
00:09:02,520 --> 00:09:04,760
去声明Data Layer是怎么组成的
235
00:09:04,920 --> 00:09:07,560
这种也是protobuffer的写的格式
236
00:09:07,560 --> 00:09:10,000
那右边就是卷积层
237
00:09:10,520 --> 00:09:14,080
通过这种方式去表示卷积层
238
00:09:15,640 --> 00:09:17,920
下面看一下两个AI框架有什么区别
239
00:09:18,600 --> 00:09:20,520
像Caffe这种早期的AI框架
240
00:09:20,640 --> 00:09:22,000
是使用protobuffer的格式
241
00:09:22,120 --> 00:09:24,320
去写网络模型的定义的
242
00:09:24,320 --> 00:09:26,440
而后来TensorFlow确实觉得
243
00:09:26,440 --> 00:09:28,280
大家去写这种网络模型的定义
244
00:09:28,600 --> 00:09:30,920
去写底层的这些protobuffer很容易出错
245
00:09:30,920 --> 00:09:33,600
那还不如通过python去封装好
246
00:09:33,600 --> 00:09:36,360
然后给到TFTensorFlow去封装好的API
247
00:09:36,360 --> 00:09:37,520
给用户去调
248
00:09:37,520 --> 00:09:40,000
然后通过简单的去调一些API
249
00:09:40,000 --> 00:09:42,360
就可以把protobuffer给调起来
250
00:09:42,360 --> 00:09:43,880
去写网络模型