您的位置:首页 > 编程语言

keras中实现3D卷积(Con3D)以及如何将输入数据转化为3D卷积的输入(后者附实现代码)

2018-10-27 00:09 302 查看

【时间】2018.10.26

【题目】keras中实现3D卷积(Con3D)以及如何将输入数据转化为3D卷积的输入(附实现代码)

概述

      keras中实现3D卷积使用的是keras.layers.convolutional.Conv3D 函数。而在‘channels_last’模式下,3D卷积输入应为形如(samples,input_dim1,input_dim2, input_dim3,channels)的5D张量。本文讲述了Con3D的使用方法,但更主要的是讲述如何将输入数据转化为符合3D卷积的输入的形式。

一、Keras中的Con3D层

(注:此部分的内容来自《Keras中文文档》

链接为:https://keras-cn.readthedocs.io/en/latest/layers/convolutional_layer/

 

[code]keras.layers.convolutional.Conv3D(filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

三维卷积对三维的输入进行滑动窗卷积,当使用该层作为第一层时,应提供input_shape参数。例如input_shape = (3,10,128,128)代表对10帧128*128的彩色RGB图像进行卷积。数据的通道位置仍然有data_format参数指定。

参数

  • filters:卷积核的数目(即输出的维度)

  • kernel_size:单个整数或由3个整数构成的list/tuple,卷积核的宽度和长度。如为单个整数,则表示在各个空间维度的相同长度。

  • strides:单个整数或由3个整数构成的list/tuple,为卷积的步长。如为单个整数,则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation_rate均不兼容

  • padding:补0策略,为“valid”, “same” 。“valid”代表只进行有效的卷积,即对边界数据不处理。“same”代表保留边界处的卷积结果,通常会导致输出shape与输入shape相同。

  • activation:激活函数,为预定义的激活函数名(参考激活函数),或逐元素(element-wise)的Theano函数。如果不指定该参数,将不会使用任何激活函数(即使用线性激活函数:a(x)=x)

  • dilation_rate:单个整数或由3个整数构成的list/tuple,指定dilated convolution中的膨胀比例。任何不为1的dilation_rate均与任何不为1的strides不兼容。

  • data_format:字符串,“channels_first”或“channels_last”之一,代表数据的通道维的位置。该参数是Keras 1.x中的image_dim_ordering,“channels_last”对应原本的“tf”,“channels_first”对应原本的“th”。以128x128x128的数据为例,“channels_first”应将数据组织为(3,128,128,128),而“channels_last”应将数据组织为(128,128,128,3)。该参数的默认值是~/.keras/keras.json中设置的值,若从未设置过,则为“channels_last”。

  • use_bias:布尔值,是否使用偏置项

  • kernel_initializer:权值初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。参考initializers

  • bias_initializer:权值初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。参考initializers

  • kernel_regularizer:施加在权重上的正则项,为Regularizer对象

  • bias_regularizer:施加在偏置向量上的正则项,为Regularizer对象

  • activity_regularizer:施加在输出上的正则项,为Regularizer对象

  • kernel_constraints:施加在权重上的约束项,为Constraints对象

  • bias_constraints:施加在偏置上的约束项,为Constraints对象

输入shape

‘channels_first’模式下,输入应为形如(samples,channels,input_dim1,input_dim2, input_dim3)的5D张量

‘channels_last’模式下,输入应为形如(samples,input_dim1,input_dim2, input_dim3,channels)的5D张量

这里的输入shape指的是函数内部实现的输入shape,而非函数接口应指定的input_shape。

 

二、如何将输入数据转化为符合3D卷积的输入的形式

   3D卷积输入应为形如(samples,input_dim1,input_dim2, input_dim3,channels)的5D张量,如(10000,10,128,,128,3)表示输入是10帧 128*128的彩色RGB图像构成的图像块,共有10000个图像块。而一般我们的彩色RGB图像为3D张量,如(128,128,3),那么如何将它转化为符合3D卷积输入的5D张量呢?这里主要使用numpy中的reshape()函数改变图像array的shape,在使用numpy中的concatenate()函数进行数组array合并。具体如下:(以(128,128,3)---》(10000,10,128,,128,3)为例)

1、获取图片中所有的文件名,这里可以使用os.listdir()函数,如:

[code]    # image_path是文件路径

    filenames = os.listdir(image_path)

2、读取图片文件

  这里可以使用cv2.imread()函数进行读取,得到的结果是类似于(128,128,3)的数组array,如:

[code]     im1= cv2.imread('C:/01.jpg')

     im2= cv2.imread('C:/02.pg')

3、使用np.reshape()改变数组的维度,改变为(1,128,128,3),如:

[code]   im1 = im1.reshape((1,128,128,3))

   im2 = im2.reshape((1,128,128,3))

4、使用np.concatenate()函数进行合并,如:

[code]# im1,im2表示要合并的array,axis表示要合并的维度

 im10 = np.concatenate((im1,im2), axis = 0)

5、每合并完10张图片,都将得到类似于(10,128,128,3)的4D张量,这时,只需要再进行一次reshape和concatenate即可的到想要的5D张量,如

[code]im10_1 = reshape(1,10,128,128,3)

im10_2 = reshape(1,10,128,128,3)

im =np.concatenate((im10_1,im10_2), axis = 0)

【最终的代码】:

[code]import cv2

import os

import numpy  as np

# image_path是文件路径,此路径中有690张图片

image_path = "F:\\image"

def image2array(image_path ):

    filenames = os.listdir(image_path)

    image_num = len(filenames)

    cube_num = int(image_num /10)

    image_name = image_path + '\\' + filenames[0]

    Img = cv2.imread(image_name)

    Img =Img.reshape(1,Img.shape[0], Img.shape[1],Img.shape[2])

    Img10 = Img

    for k in range(1, 10):

        image_name = image_path + '\\' + filenames[k]

        Img = cv2.imread(image_name)

        Img = Img.reshape(1, Img.shape[0], Img.shape[1], Img.shape[2])

        Img10 = np.concatenate((Img10, Img), axis=0)

    cube = Img10.reshape(1,Img10.shape[0], Img10.shape[1], Img10.shape[2], Img10.shape[3])

    for i in range(1, cube_num):

        index = 10 * i

        image_name = image_path + '\\' + filenames[index]

        Img = cv2.imread(image_name)

        Img = Img.reshape(1, Img.shape[0], Img.shape[1], Img.shape[2])

        Img10 = Img

        for k in range(1, 10):

            image_name = image_path + '\\' + filenames[index+k]

            Img = cv2.imread(image_name)

            Img = Img.reshape(1, Img.shape[0], Img.shape[1], Img.shape[2])

            Img10 = np.concatenate((Img10, Img), axis=0)

        Img10 = Img10.reshape(1, Img10.shape[0], Img10.shape[1], Img10.shape[2], Img10.shape[3])

        cube = np.concatenate((cube,Img10), axis=0)

    return cube

if __name__  == "__main__" :

    cube = image2array(image_path)
    print(cube.shape)

【运行结果】:

 

 

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐