上个月发布了四篇文章,主要讲了深度学习中的“hello world”----mnist图像识别,以及卷积神经网络的原理详解,包括基本原理、自己手写CNN和paddlepaddle的源码解析。这篇主要跟大家讲讲如何用PaddlePaddle和Tensorflow做图像分类。所有程序都在我的github里,可以自行下载训练。

  在卷积神经网络中,有五大经典模型,分别是:LeNet-5,AlexNet,GoogleNet,Vgg和ResNet。本文首先自己设计一个小型CNN网络结构来对图像进行分类,再了解一下LeNet-5网络结构对图像做分类,并用比较流行的Tensorflow框架和百度的PaddlePaddle实现LeNet-5网络结构,并对结果对比。


 什么是图像分类

  图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等(引用自官网)

 cifar-10数据集

  CIFAR-10分类问题是机器学习领域的一个通用基准,由60000张32*32的RGB彩色图片构成,共10个分类。50000张用于训练集,10000张用于测试集。其问题是将32X32像素的RGB图像分类成10种类别:飞机手机鹿青蛙卡车。更多信息可以参考CIFAR-10和Alex Krizhevsky的演讲报告。常见的还有cifar-100,分类物体达到100类,以及ILSVRC比赛的100类。

 


自己设计CNN

  了解CNN的基本网络结构后,首先自己设计一个简单的CNN网络结构对cifar-10数据进行分类。

  网络结构

  代码实现

  1.网络结构:simple_cnn.py

 1 #coding:utf-82 '''3 Created by huxiaoman 2017.11.274 simple_cnn.py:自己设计的一个简单的cnn网络结构5 '''6 7 import os8 from PIL import Image9 import numpy as np
10 import paddle.fluid as fluid
11 from paddle.trainer_config_helpers import *
12
13 with_gpu = os.getenv('WITH_GPU', '0') != '1'
14
15 def simple_cnn(img):
16     conv_pool_1 = paddle.networks.simple_img_conv_pool(
17         input=img,
18         filter_size=5,
19         num_filters=20,
20         num_channel=3,
21         pool_size=2,
22         pool_stride=2,
23         act=paddle.activation.Relu())
24     conv_pool_2 = paddle.networks.simple_img_conv_pool(
25         input=conv_pool_1,
26         filter_size=5,
27         num_filters=50,
28         num_channel=20,
29         pool_size=2,
30         pool_stride=2,
31         act=paddle.activation.Relu())
32     fc = paddle.layer.fc(
33         input=conv_pool_2, size=512, act=paddle.activation.Softmax())

  2.训练程序:train_simple_cnn.py

  1 #coding:utf-82 '''3 Created by huxiaoman 2017.11.274 train_simple—_cnn.py:训练simple_cnn对cifar10数据集进行分类5 '''6 import sys, os7 8 import paddle.v2 as paddle9 from simple_cnn import simple_cnn10 11 with_gpu = os.getenv('WITH_GPU', '0') != '1'12 13 14 def main():15     datadim = 3 * 32 * 3216     classdim = 1017 18     # PaddlePaddle init19     paddle.init(use_gpu=with_gpu, trainer_count=7)20 21     image = paddle.layer.data(22         name="image", type=paddle.data_type.dense_vector(datadim))23 24     # Add neural network config25     # option 1. resnet26     # net = resnet_cifar10(image, depth=32)27     # option 2. vgg28     net = simple_cnn(image)29 30     out = paddle.layer.fc(31         input=net, size=classdim, act=paddle.activation.Softmax())32 33     lbl = paddle.layer.data(34         name="label", type=paddle.data_type.integer_value(classdim))35     cost = paddle.layer.classification_cost(input=out, label=lbl)36 37     # Create parameters38     parameters = paddle.parameters.create(cost)39 40     # Create optimizer41     momentum_optimizer = paddle.optimizer.Momentum(42         momentum=0.9,43         regularization=paddle.optimizer.L2Regularization(rate=0.0002 * 128),44         learning_rate=0.1 / 128.0,45         learning_rate_decay_a=0.1,46         learning_rate_decay_b=50000 * 100,47         learning_rate_schedule='discexp')48 49     # End batch and end pass event handler50     def event_handler(event):51         if isinstance(event, paddle.event.EndIteration):52             if event.batch_id % 100 == 0:53                 print "\nPass %d, Batch %d, Cost %f, %s" % (54                     event.pass_id, event.batch_id, event.cost, event.metrics)55             else:56                 sys.stdout.write('.')57                 sys.stdout.flush()58         if isinstance(event, paddle.event.EndPass):59             # save parameters60             with open('params_pass_%d.tar' % event.pass_id, 'w') as f:61                 parameters.to_tar(f)62 63             result = trainer.test(64                 reader=paddle.batch(65                     paddle.dataset.cifar.test10(), batch_size=128),66                 feeding={'image': 0,67                          'label': 1})68             print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)69 70     # Create trainer71     trainer = paddle.trainer.SGD(72         cost=cost, parameters=parameters, update_equation=momentum_optimizer)73 74     # Save the inference topology to protobuf.75     inference_topology = paddle.topology.Topology(layers=out)76     with open("inference_topology.pkl", 'wb') as f:77         inference_topology.serialize_for_inference(f)78 79     trainer.train(80         reader=paddle.batch(81             paddle.reader.shuffle(82                 paddle.dataset.cifar.train10(), buf_size=50000),83             batch_size=128),84         num_passes=200,85         event_handler=event_handler,86         feeding={'image': 0,87                  'label': 1})88 89     # inference90     from PIL import Image91     import numpy as np92     import os93 94     def load_image(file):95         im = Image.open(file)96         im = im.resize((32, 32), Image.ANTIALIAS)97         im = np.array(im).astype(np.float32)98         # The storage order of the loaded image is W(widht),99         # H(height), C(channel). PaddlePaddle requires
100         # the CHW order, so transpose them.
101         im = im.transpose((2, 0, 1))  # CHW
102         # In the training phase, the channel order of CIFAR
103         # image is B(Blue), G(green), R(Red). But PIL open
104         # image in RGB mode. It must swap the channel order.
105         im = im[(2, 1, 0), :, :]  # BGR
106         im = im.flatten()
107         im = im / 255.0
108         return im
109
110     test_data = []
111     cur_dir = os.path.dirname(os.path.realpath(__file__))
112     test_data.append((load_image(cur_dir + '/image/dog.png'), ))
113
114     # users can remove the comments and change the model name
115     # with open('params_pass_50.tar', 'r') as f:
116     #    parameters = paddle.parameters.Parameters.from_tar(f)
117
118     probs = paddle.infer(
119         output_layer=out, parameters=parameters, input=test_data)
120     lab = np.argsort(-probs)  # probs and lab are the results of one batch data
121     print "Label of image/dog.png is: %d" % lab[0][0]
122
123
124 if __name__ == '__main__':
125     main()

  

  3.结果输出

 1 I1128 21:44:30.218085 14733 Util.cpp:166] commandline:  --use_gpu=True --trainer_count=72 [INFO 2017-11-28 21:44:35,874 layers.py:2539] output for __conv_pool_0___conv: c = 20, h = 28, w = 28, size = 156803 [INFO 2017-11-28 21:44:35,874 layers.py:2667] output for __conv_pool_0___pool: c = 20, h = 14, w = 14, size = 39204 [INFO 2017-11-28 21:44:35,875 layers.py:2539] output for __conv_pool_1___conv: c = 50, h = 10, w = 10, size = 50005 [INFO 2017-11-28 21:44:35,876 layers.py:2667] output for __conv_pool_1___pool: c = 50, h = 5, w = 5, size = 12506 I1128 21:44:35.881502 14733 MultiGradientMachine.cpp:99] numLogicalDevices=1 numThreads=7 numDevices=87 I1128 21:44:35.928449 14733 GradientMachine.cpp:85] Initing parameters..8 I1128 21:44:36.056259 14733 GradientMachine.cpp:92] Init parameters done.9
10 Pass 0, Batch 0, Cost 2.302628, {'classification_error_evaluator': 0.9296875}
11 ................................................................................
12 ```
13 Pass 199, Batch 200, Cost 0.869726, {'classification_error_evaluator': 0.3671875}
14 ...................................................................................................
15 Pass 199, Batch 300, Cost 0.801396, {'classification_error_evaluator': 0.3046875}
16 ..........................................................................................I1128 23:21:39.443141 14733 MultiGradientMachine.cpp:99] numLogicalDevices=1 numThreads=7 numDevices=8
17
18 Test with Pass 199, {'classification_error_evaluator': 0.5248000025749207}
19 Label of image/dog.png is: 9

  我开了7个线程,用了8个Tesla K80 GPU训练,batch_size = 128,迭代次数200次,耗时1h37min,错误分类率为0.5248,这个结果,emm,不算很高,我们可以把它作为一个baseline,后面对其进行调优。

  


LeNet-5网络结构

  Lenet-5网络结构来源于Yan LeCun提出的,原文为《Gradient-based learning applied to document recognition》,论文里使用的是mnist手写数字作为输入数据(32 * 32)进行验证。我们来看一下网络结构。

  LeNet-5一共有8层: 1个输入层+3个卷积层(C1、C3、C5)+2个下采样层(S2、S4)+1个全连接层(F6)+1个输出层,每层有多个feature map(自动提取的多组特征)。

  Input输入层

 cifar10 数据集,每一张图片尺寸:32 * 32

  C1 卷积层

  • 6个feature_map,卷积核大小 5 * 5 ,feature_map尺寸:28 * 28
  • 每个卷积神经元的参数数目:5 * 5 = 25个和一个bias参数
  • 连接数目:(5*5+1)* 6 *(28*28) = 122,304
  • 参数共享:每个feature_map内共享参数,∴∴共(5*5+1)*6 = 156个参数

  S2 下采样层(池化层)

  • 6个14*14的feature_map,pooling大小 2* 2
  • 每个单元与上一层的feature_map中的一个2*2的滑动窗口连接,不重叠,因此S2每个feature_map大小是C1中feature_map大小的1/4
  • 连接数:(2*2+1)*1*14*14*6 = 5880个
  • 参数共享:每个feature_map内共享参数,有2 * 6 = 12个训练参数

  C3 卷积层

  这层略微复杂,S2神经元与C3是多对多的关系,比如最简单方式:用S2的所有feature map与C3的所有feature map做全连接(也可以对S2抽样几个feature map出来与C3某个feature map连接),这种全连接方式下:6个S2的feature map使用6个独立的5×5卷积核得到C3中1个feature map(生成每个feature map时对应一个bias),C3中共有16个feature map,所以该层需要学习的参数个数为:(5×5×6+1)×16=2416个,神经元连接数为:2416×8×8=154624个。

  S4 下采样层

  同S2,如果采用Max Pooling/Mean Pooling,则该层需要学习的参数个数为0个,神经元连接数为:(2×2+1)×16×4×4=1280个。

  C5卷积层

  类似C3,用S4的所有feature map与C5的所有feature map做全连接,这种全连接方式下:16个S4的feature map使用16个独立的1×1卷积核得到C5中1个feature map(生成每个feature map时对应一个bias),C5中共有120个feature map,所以该层需要学习的参数个数为:(1×1×16+1)×120=2040个,神经元连接数为:2040个。

  F6 全连接层

  将C5层展开得到4×4×120=1920个节点,并接一个全连接层,考虑bias,该层需要学习的参数和连接个数为:(1920+1)*84=161364个。

  输出层

  该问题是个10分类问题,所以有10个输出单元,通过softmax做概率归一化,每个分类的输出单元对应84个输入。

    


LeNet-5的PaddlePaddle实现

  1.网络结构 lenet.py

 1 #coding:utf-82 '''3 Created by huxiaoman 2017.11.274 lenet.py:LeNet-55 '''6 7 import os8 from PIL import Image9 import numpy as np
10 import paddle.v2 as paddle
11 from paddle.trainer_config_helpers import *
12
13 with_gpu = os.getenv('WITH_GPU', '0') != '1'
14
15 def lenet(img):
16     conv_pool_1 = paddle.networks.simple_img_conv_pool(
17         input=img,
18         filter_size=5,
19         num_filters=6,
20         num_channel=3,
21         pool_size=2,
22         pool_stride=2,
23         act=paddle.activation.Relu())
24     conv_pool_2 = paddle.networks.simple_img_conv_pool(
25         input=conv_pool_1,
26         filter_size=5,
27         num_filters=16,
28         pool_size=2,
29         pool_stride=2,
30         act=paddle.activation.Relu())
31     conv_3 = img_conv_layer(
32         input = conv_pool_2,
33         filter_size = 1,
34         num_filters = 120,
35         stride = 1)
36     fc = paddle.layer.fc(
37         input=conv_3, size=84, act=paddle.activation.Sigmoid())
38     return fc

  2.训练代码 train_lenet.py

  1 #coding:utf-82 '''3 Created by huxiaoman 2017.11.274 train_lenet.py:训练LeNet-5对cifar10数据集进行分类5 '''6 7 import sys, os8 9 import paddle.v2 as paddle10 from lenet import lenet11 12 with_gpu = os.getenv('WITH_GPU', '0') != '1'13 14 15 def main():16     datadim = 3 * 32 * 3217     classdim = 1018 19     # PaddlePaddle init20     paddle.init(use_gpu=with_gpu, trainer_count=7)21 22     image = paddle.layer.data(23         name="image", type=paddle.data_type.dense_vector(datadim))24 25     # Add neural network config26     # option 1. resnet27     # net = resnet_cifar10(image, depth=32)28     # option 2. vgg29     net = lenet(image)30 31     out = paddle.layer.fc(32         input=net, size=classdim, act=paddle.activation.Softmax())33 34     lbl = paddle.layer.data(35         name="label", type=paddle.data_type.integer_value(classdim))36     cost = paddle.layer.classification_cost(input=out, label=lbl)37 38     # Create parameters39     parameters = paddle.parameters.create(cost)40 41     # Create optimizer42     momentum_optimizer = paddle.optimizer.Momentum(43         momentum=0.9,44         regularization=paddle.optimizer.L2Regularization(rate=0.0002 * 128),45         learning_rate=0.1 / 128.0,46         learning_rate_decay_a=0.1,47         learning_rate_decay_b=50000 * 100,48         learning_rate_schedule='discexp')49 50     # End batch and end pass event handler51     def event_handler(event):52         if isinstance(event, paddle.event.EndIteration):53             if event.batch_id % 100 == 0:54                 print "\nPass %d, Batch %d, Cost %f, %s" % (55                     event.pass_id, event.batch_id, event.cost, event.metrics)56             else:57                 sys.stdout.write('.')58                 sys.stdout.flush()59         if isinstance(event, paddle.event.EndPass):60             # save parameters61             with open('params_pass_%d.tar' % event.pass_id, 'w') as f:62                 parameters.to_tar(f)63 64             result = trainer.test(65                 reader=paddle.batch(66                     paddle.dataset.cifar.test10(), batch_size=128),67                 feeding={'image': 0,68                          'label': 1})69             print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)70 71     # Create trainer72     trainer = paddle.trainer.SGD(73         cost=cost, parameters=parameters, update_equation=momentum_optimizer)74 75     # Save the inference topology to protobuf.76     inference_topology = paddle.topology.Topology(layers=out)77     with open("inference_topology.pkl", 'wb') as f:78         inference_topology.serialize_for_inference(f)79 80     trainer.train(81         reader=paddle.batch(82             paddle.reader.shuffle(83                 paddle.dataset.cifar.train10(), buf_size=50000),84             batch_size=128),85         num_passes=200,86         event_handler=event_handler,87         feeding={'image': 0,88                  'label': 1})89 90     # inference91     from PIL import Image92     import numpy as np93     import os94 95     def load_image(file):96         im = Image.open(file)97         im = im.resize((32, 32), Image.ANTIALIAS)98         im = np.array(im).astype(np.float32)99         # The storage order of the loaded image is W(widht),
100         # H(height), C(channel). PaddlePaddle requires
101         # the CHW order, so transpose them.
102         im = im.transpose((2, 0, 1))  # CHW
103         # In the training phase, the channel order of CIFAR
104         # image is B(Blue), G(green), R(Red). But PIL open
105         # image in RGB mode. It must swap the channel order.
106         im = im[(2, 1, 0), :, :]  # BGR
107         im = im.flatten()
108         im = im / 255.0
109         return im
110
111     test_data = []
112     cur_dir = os.path.dirname(os.path.realpath(__file__))
113     test_data.append((load_image(cur_dir + '/image/dog.png'), ))
114
115     # users can remove the comments and change the model name
116     # with open('params_pass_50.tar', 'r') as f:
117     #    parameters = paddle.parameters.Parameters.from_tar(f)
118
119     probs = paddle.infer(
120         output_layer=out, parameters=parameters, input=test_data)
121     lab = np.argsort(-probs)  # probs and lab are the results of one batch data
122     print "Label of image/dog.png is: %d" % lab[0][0]
123
124
125 if __name__ == '__main__':
126     main()

  3.结果输出 

 1 I1129 14:52:44.314946 15153 Util.cpp:166] commandline:  --use_gpu=True --trainer_count=72 [INFO 2017-11-29 14:52:50,490 layers.py:2539] output for __conv_pool_0___conv: c = 6, h = 28, w = 28, size = 47043 [INFO 2017-11-29 14:52:50,491 layers.py:2667] output for __conv_pool_0___pool: c = 6, h = 14, w = 14, size = 11764 [INFO 2017-11-29 14:52:50,491 layers.py:2539] output for __conv_pool_1___conv: c = 16, h = 10, w = 10, size = 16005 [INFO 2017-11-29 14:52:50,492 layers.py:2667] output for __conv_pool_1___pool: c = 16, h = 5, w = 5, size = 4006 [INFO 2017-11-29 14:52:50,493 layers.py:2539] output for __conv_0__: c = 120, h = 5, w = 5, size = 30007 I1129 14:52:50.498749 15153 MultiGradientMachine.cpp:99] numLogicalDevices=1 numThreads=7 numDevices=88 I1129 14:52:50.545882 15153 GradientMachine.cpp:85] Initing parameters..9 I1129 14:52:50.651103 15153 GradientMachine.cpp:92] Init parameters done.
10
11 Pass 0, Batch 0, Cost 2.331898, {'classification_error_evaluator': 0.9609375}
12 ```
13 ......
14 Pass 199, Batch 300, Cost 0.004373, {'classification_error_evaluator': 0.0}
15 ..........................................................................................I1129 16:17:08.678097 15153 MultiGradientMachine.cpp:99] numLogicalDevices=1 numThreads=7 numDevices=8
16
17 Test with Pass 199, {'classification_error_evaluator': 0.39579999446868896}
18 Label of image/dog.png is: 7

  同样是7个线程,8个Tesla K80 GPU,batch_size = 128,迭代次数200次,耗时1h25min,错误分类率为0.3957,相比与simple_cnn的0.5248提高了12.91%。当然,这个结果也并不是很好,如果输出详细的日志,可以看到在训练的过程中loss先降后升,说明有一定程度的过拟合,对于如何防止过拟合,我们在后面会详细讲解。

  有一个可视化CNN的网站可以对mnist和cifar10分类的网络结构进行可视化,这是cifar-10 BaseCNN的网络结构:


LeNet-5的Tensorflow实现

  tensorflow版本的LeNet-5版本的可以参照models/tutorials/image/cifar10/(https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10)的步骤来训练,不过这里面的代码包含了很多数据处理、权重衰减以及正则化的一些方法防止过拟合。按照官方写的,batch_size=128时在Tesla K40上迭代10w次需要4小时,准确率能达到86%。不过如果不对数据做处理,直接跑的话,效果应该没有这么好。不过可以仔细借鉴cifar10_inputs.py里的distorted_inouts函数对数据预处理增大数据集的思想,以及cifar10.py里对于权重和偏置的衰减设置等。目前迭代到1w次左右,cost是0.98,acc是78.4%

  对于未进行数据处理的cifar10我准备也跑一次,看看效果如何,与paddle的结果对比一下。不过得等到周末再补上了 = =


总结

  本节用常规的cifar-10数据集做图像分类,用了三种实现方式,第一种是自己设计的一个简单的cnn,第二种是LeNet-5,第三种是Tensorflow实现的LeNet-5,对比速度可以见一下表格:

  可以看到LeNet-5相比于原始的simple_cnn在准确率和速度方面都有一定的的提升,等tensorflow版本跑完后可以把结果加上去再对比一下。不过用Lenet-5网络结构后,结果虽然有一定的提升,但是还是不够理想,在日志里看到loss的信息基本可以推断出是过拟合,对于神经网络训练过程中出现的过拟合情况我们应该如何避免,下期我们讲着重讲解。此外在下一节将介绍AlexNet,并对分类做一个实验,对比其效果。

参考文献

1.LeNet-5论文:《Gradient-based learning applied to document recognition》

2.可视化CNN:http://shixialiu.com/publications/cnnvis/demo/

 

作者:Charlotte77

出处:http://www.cnblogs.com/charlotte77/

本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!

关注【Charlotte数据挖掘】回复 '资料' 获取深度学习优质资料

【深度学习系列】用Tensorflow进行图像分类相关推荐

  1. 资源 | Intel发布AI免费系列课程3部曲:机器学习基础、深度学习基础以及TensorFlow基础

    翻译 | AI科技大本营(公众号ID:rgznai100) 校对 | 成龙 编辑 | 明明 Intel于近期发布了三门AI系列的免费课程,分别是关于机器学习基础.深度学习基础.TensorFlow基础 ...

  2. 深度学习系列笔记——贰 (基于Tensorflow Keras搭建的猫狗大战模型 一)

    猫狗大战是著名的竞赛网站kaggle几年前的一个比赛,参赛者得到猫狗各12500张图片,作为训练集,另外还会得到12500张猫和狗的图片,作为验证.最后提交结果至kaggle平台,获得评测分数. 本篇 ...

  3. 常用深度学习框——Caffe/TensorFlow / Keras/ PyTorch/MXNet

    常用深度学习框--Caffe/TensorFlow / Keras/ PyTorch/MXNet 一.概述 近几年来,深度学习的研究和应用的热潮持续高涨,各种开源深度学习框架层出不穷,包括Tensor ...

  4. 深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测...

    前言 深度学习在图像处理.语音识别.自然语言处理领域的应用取得了巨大成功,但是它通常在功能强大的服务器端进行运算.如果智能手机通过网络远程连接服务器,也可以利用深度学习技术,但这样可能会很慢,而且只有 ...

  5. 深度学习系列:深度学习在腾讯的平台化和应用实践

    深度学习系列:深度学习在腾讯的平台化和应用实践(一) 莫扎特 2015-01-04 6:05:13 大数据技术 评论(0) 深度学习是近年机器学习领域的重大突破,有着广泛的应用前景.随着Google公 ...

  6. 【AI初识境】深度学习模型评估,从图像分类到生成模型

    文章首发于微信公众号<有三AI> [AI初识境]深度学习模型评估,从图像分类到生成模型 这是<AI初识境>第10篇,这次我们说说深度学习模型常用的评价指标.所谓初识,就是对相关 ...

  7. python系列文章(基础,应用,后端,运维,自动化测试,爬虫,数据分析,可视化,机器学习,深度学习系列内容)

    python基础教程 python基础系列教程--Python的安装与测试:python解释器.PyDev编辑器.pycharm编译器 python基础系列教程--Python库的安装与卸载 pyth ...

  8. 辣鸡准备稍微碰一下深度学习系列(1/21)---上

    Hello Tensorflow(2.3.0)集ctrlCV之大成 -- MNIST 手写数字检测上 前BB MNIST数据集 一.是啥玩意? 二.怎么得到? 第一种:找大腿(keras) 第二种:伸 ...

  9. 深度学习入门笔记(十五):深度学习框架(TensorFlow和Pytorch之争)

    欢迎关注WX公众号:[程序员管小亮] 专栏--深度学习入门笔记 声明 1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献. 2)本文仅供学术交流,非商用.所以每一部分具 ...

  10. 深度学习系列笔记——贰 (基于Tensorflow2 Keras搭建的猫狗大战模型 三)

    深度学习系列笔记--贰 (基于Tensorflow Keras搭建的猫狗大战模型 一) 深度学习系列笔记--贰 (基于Tensorflow Keras搭建的猫狗大战模型 二) 前面两篇博文已经介绍了如 ...

最新文章

  1. java 按顺序取出json_java取json 的方法
  2. oracle 的目录是空的,oracle sqlplus在@命令路径中有空格的问题
  3. Angular——单页面与路由的使用
  4. poi报空指针_POI 导出文件 报空指针异常 --Docker 中
  5. 数据聚合Spring Data MongoDB:嵌套结果
  6. Mysql复制-Slave库设置复制延迟
  7. python中计算整商的运算符_Python 运算符中用来计算整商的是( ). (2.0分)_学小易找答案...
  8. Net::SSH::Perl 包 与 Net::OpenSSH 包的 性能对比代码
  9. 协方差矩阵经线性变化可以变成不相关的
  10. [礼仪大赛策划方案]图:如何打造一场精美极致的礼仪大赛?PPT动态柱状图,如何动态显示?Flash如何渲染PPT界面呢?
  11. ollvm源码分析之虚假控制流(2)
  12. 【转】Gnuplot基本介绍
  13. 华为端口聚合命令_华为交换机链路聚合命令
  14. SQL注入攻击原理及防御策略
  15. Oracle9iClient简化版的安装与tnsnames配置,sqlplus的连接
  16. PCHunter_32X64_2022_03最新版
  17. ypid编码是什么_国家药品供应保障综合管理信息平台YPID编码规则与应用
  18. Python实现繁体字和简体字的相互转换
  19. linux 7 查看网卡配置文件,如何查询centos网卡配置文件
  20. R语言绘图基础篇-柱状图加误差棒

热门文章

  1. Android实战 - 个人乐逗项目 (项目改动,优化和总结)
  2. Java中int 转为char的方法
  3. 2010年最大的ERP失败案例(1)
  4. 在Map对象中获取属性,注意判断为空
  5. Go语言实现TCP服务端和客户端
  6. 如何自动注销Linux服务器系统中不活动的用户
  7. QWebEngineView无法输入中文
  8. [杂想]浑浑噩噩度日
  9. 人脸识别 (3) FaceNet安装与测试
  10. java学习第13天