迁移学习:实战学习入门对Inception-v3进行引用

  • A+
所属分类:深度学习

人类的学习迁移

学习迁移是指一种学习对另一种学习的影响,或习得的经验对完成其他活动的影响。迁移广泛存在于各种知识、技能与社会规范的学习中。由于学习活动总是建立在已有的知识经验之上的,这种利用已有的知识经验不断地获得新知识和技能的过程,可以认为是广义的学习迁移; 而新知识技能的获得也不断地使已有的知识经验得到扩充和丰富,这就是我们常说的“举一反三”、“触类旁通”,这个过程也属于广义的学习迁移。教育心理学所研究的学习迁移是狭义的迁移,特指前一种学习对后一种学习的影响或者后一种学习对前一种学习的影响。20 世纪以来教育心理学家关于学习迁移的研究,就是通过设计两种学习情境,看一种学习对另一种学习的影响。------百度百科

相对于我们深度学习的开发者来说,人类的这种“举一反三”的能力能不能运用在深度学习的神经网络中呢?

当然是可以的,早很早以前就有人去研究了。

今天我就不讲这些历史了,我们从一个简单的例子去看,去体验下迁移学习的基本方法。

在看实例之前我们先简单了解下迁移的方式归类有哪些。

基于样本的迁移学习

  • 通过调整 源Domain的标签(辅助) 和 目标Domain标签的权重,协同训练得到目标模型。
  • 非专业解释:比如你已经有一个模型,学会了猫 、狗、鸡和鸭的4分类模型,你现在要做另外一个模型区分四条腿的动物和两条腿的动物,那么之前的模型样本是不是可以迁移过来用?

 

基于特征的迁移学习

  • 找到 “好”特征 来减少源Domain和目标Domain之间的不同,能够降低分类、回归误差。
  • 非专业解释:比如一个小孩子,被狗咬过,他记住了狗锋利的牙齿,当有一天他来到动物园看到老虎,这种特征是不是很好判断,一下子就被人类迁移过来了,所以他害怕。同样的在我们深度学习模型中也是这样的,比如图像,在imageNet的很多模型中已经学习到了足够多的特征,当某一天我们模型要对图像进行特征判断的时候可以总以前的模型中运用。

 

基于参数的迁移学习

  • 发现源Domain和目标Domain之间的共享参数或先验关系。
  • 非专业解释:你们肯定有这样的学习经历,你学习了数学的一元二次方程的求解,某一天你考物理的时候,突然用数学的一元二次方程解答出来。这种就是参数,或者说函数之间的一种共享关系,比如,物理上的匀速运动的速度求解问题,用数学的平均数的知识肯定是可以解答的。我们模型也是一样的,有些具有相关的函数的神经网络也是可以迁移的,但是前提条件很苛刻,需要对模型的网络非常的了解。

 

基于相关性的迁移学习

 

问题的思考

现在我们要进行一个图片分类。比如是一个猫和狗的分类,我们数据并没有那么多,那么我就想用Google的Inception-v3进行迁移,我的代码应该怎么写。

我们知道Inception-v3对图像的抽取,和样本数已经是很成熟的了,我们提取这个Inception模型的某一个特定的层。

当然你要对Inception模型有所了解,知道是抽取哪一个层,有什么特征。

然后呢?

把我们的图像数据输入到它的层级当中,因为它的层级已经是模块化了的,相当于它给我们进行了一层过滤,然后我们再进行我们的layer。

当然为了理解方便我们的layer就取一个wb模型,简单方便。大概的思路如下

代码书写

inception_pool_3 = 'pool_3/_reshape:0'
image_data_type = 'DecodeJpeg/contents:0'
inception_modle= 'tensorflow_inception_graph.pb'

    with gfile.FastGFile(os.path.join("./",inception_modle), 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

 

  • 我们加载inception模型
bottleneck_tensor, jpeg_data_tensor = tf.import_graph_def(
    graph_def, return_elements=[inception_pool_3, image_data_type])

 

  • 我们加载我们需要的那一层和数据变量
def inception_layer(sess, image_data,image_data_type, inception_pool_3):
    
    new_image_data = sess.run(inception_pool_3, {image_data_tensor: image_data})

    new_image_data_squeeze = np.squeeze(new_image_data)
    return new_image_data_squeeze

 

  • 然后我们定义一层inception_layer,将我们的图像数据给这个层过滤一遍提取特征,返回新的数据
def ourself_layer(new_image_data_squeeze):
with tf.name_scope('final_training_ops'):
        w = tf.Variable(tf.truncated_normal([size, n_classes], stddev=0.01))
        b = tf.Variable(tf.zeros([n_classes]))
        y = tf.matmul(new_image_data_squeeze, w) + b
        
    # 定义交叉熵损失函数。
    cross = tf.nn.softmax_cross_entropy_with_logits(y, labels=_y)
    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross)

 

  • 最后我们定义一层我们自己需要的层,我们定义了一个wb全连接层。做出损失函数,进行训练。
accuracy = 89.3%

 

结果显示我们用小数据量达到了接近90的准确率。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: