• (CV学习笔记)看图说话(Image Captioning)-2


    实现load_img_as_np_array

    def load_img_as_np_array(path, target_size):
        """从给定文件[加载]图像,[缩放]图像大小为给定target_size,返回[Keras支持]的浮点数numpy数组.
    
        # Arguments
            path: 图像文件路径
            target_size: 元组(图像高度, 图像宽度).
    
        # Returns
            numpy 数组.
        """
    
    使用PIL库:
    from PIL import Image as pil_image
    img = pil_image.open(file)
    img.resize(targent_size,pil_image.NEAREST)
    
    return np.asarray(img, dtype=keras.floatx())
    
    • assarray方法输入两个参数,第一个图像对象,第二个是转换的参数类型

    • floatx类型是keras的浮点类型,会自动转换为需要的数据。

    实现load_vgg16_model

    def load_vgg16_model():
        """从当前目录下面的 vgg16_exported.json 和 vgg16_exported.h5 两个文件中导入 VGG16 网络并返回创建的网络模型
    
        # Returns
    ​        创建的网络模型 model
    ​    """
    
    • json存储网络结构
    • h5存储网络权值,这个文件比较大
    from keras.models import model_from_json
    # 从json中导入网络模型
    json_file = open("vgg16_exported.json", 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    
    model = model_from_json(loaded_model_json)
    model.load_weights("vgg16_exported.h5")
    

    实现preprocess_input

    def preprocess_input(x):
        """预处理图像用于网络输入, 将图像由RGB格式转为BGR格式.
           将图像的每一个图像通道减去其均值
           均值BGR三个通道的均值分别为 103.939, 116.779, 123.68
    
        # Arguments
            x: numpy 数组, 4维.
            data_format: Data format of the image array.
    
        # Returns
            Preprocessed Numpy array.
        """
        # 'RGB'->'BGR', https://www.scivision.co/numpy-image-bgr-to-rgb/
        x = x[..., ::-1]
        mean = [103.939, 116.779, 123.68]
    
        x[..., 0] -= mean[0]
        x[..., 1] -= mean[1]
        x[..., 2] -= mean[2]
    
        return x
    
    

    实现extract_features

    def extract_features(directory):
        """提取给定文件夹中所有图像的特征, 将提取的特征保存在文件features.pkl中,
           提取的特征保存在一个dict中, key为文件名(不带.jpg后缀), value为特征值[np.array]
    
        Args:
            directory: 包含jpg文件的文件夹
    
        Returns:
            None
        """
    
    • 为了增强泛化能力,我们需要将最后一层去除,也就是VGG16最终输出的特征向量应该为4096纬。我们使用layers.pop()方法来实现。
    model.layers.pop()
        model = Model(inputs=model.inputs, outputs=model.layers[-1].output)
    

    ​ Inputs是原来的网络输出 ​ Outputs输出的是新的网络

    • 使用数据字典来存储,进行批处理。
    • 神经网络的输入纬度是四维,需要使用在最前面加一个纬度。
    features = dict()
        pbar = tqdm(total=len(listdir(directory)), desc="进度", ncols=100)
        for fn in listdir(directory):
            print("	Read file:", fn)
            fn_path = directory + '/' + fn
    
            # 返回长、宽、通道的三维张量
            arr = load_img_as_np_array(fn_path, target_size=(224,224))
    
            # 改变数组的形态,增加一个维度(批处理)—— 4维
            arr = arr.reshape((1, arr.shape[0], arr.shape[1], arr.shape[2]))
            # 预处理图像为VGG模型的输入
            arr = preprocess_input(arr)
            # 计算特征
            feature = model.predict(arr, verbose=0)
    
    
    • 存储
    id = os.path.splitext(fn)[0]
            features[id] = feature
            print("Saved. ", id)
            pbar.update(1)
    

    实现Creat_tokenizer

    截屏2020-02-26下午12.41.39 文本预处理可以通过keras实现 截屏2020-02-26下午12.48.41 文本标记实用类。 该类允许使用两种方法向量化一个文本语料库: 将每个文本转化为一个整数序列(每个整数都是词典中标记的索引); 或者将其转化为一个向量,其中每个标记的系数可以是二进制值、词频、TF-IDF权重等。 参数
    • num_words: 需要保留的最大词数,基于词频。只有最常出现的 num_words 词会被保留。
    • filters: 一个字符串,其中每个元素是一个将从文本中过滤掉的字符。默认值是所有标点符号,加上制表符和换行符,减去 ' 字符。
    • lower: 布尔值。是否将文本转换为小写。
    • split: 字符串。按该字符串切割文本。
    • char_level: 如果为 True,则每个字符都将被视为标记。
    • oov_token: 如果给出,它将被添加到 word_index 中,并用于在 text_to_sequence 调用期间替换词汇表外的单词。
    默认情况下,删除所有标点符号,将文本转换为空格分隔的单词序列(单词可能包含 ' 字符)。 这些序列然后被分割成标记列表。然后它们将被索引或向量化。 0 是不会被分配给任何单词的保留索引。

    示例:

    from keras.preprocessing.text import Tokenizer
    
    tokenizer = Tokenizer()
    lines = ['this is good', 'that is a cat']
    tokenizer.fit_on_texts(lines)
    
    results = tokenizer.texts_to_sequences(['cat is good'])
    print(results[0])
    
    

    实现create_input_data_for_one_image函数

    截屏2020-02-26下午1.28.23 截屏2020-02-26下午1.28.46
    def create_input_data(tokenizer, max_length, descriptions, photos_features, vocab_size):
        """
        从输入的图片标题list和图片特征构造LSTM的一组输入
        Args:
        :param tokenizer: 英文单词和整数转换的工具keras.preprocessing.text.Tokenizer
        :param max_length: 训练数据集中最长的标题的长度
        :param descriptions: dict, key 为图像的名(不带.jpg后缀), value 为list, 包含一个图像的几个不同的描述
        :param photos_features:  dict, key 为图像的名(不带.jpg后缀), value 为numpy array 图像的特征
        :param vocab_size: 训练集中表的单词数量
        :return: tuple:
                第一个元素为 numpy array, 元素为图像的特征, 它本身也是 numpy.array
                第二个元素为 numpy array, 元素为图像标题的前缀, 它自身也是 numpy.array
                第三个元素为 numpy array, 元素为图像标题的下一个单词(根据图像特征和标题的前缀产生) 也为numpy.array
        Examples:
            from pickle import load
            tokenizer = load(open('tokenizer.pkl', 'rb'))
            max_length = 6
            descriptions = {'1235345':['startseq one bird on tree endseq', "startseq red bird on tree endseq"],
                            '1234546':['startseq one boy play water endseq', "startseq one boy run across water endseq"]}
            photo_features = {'1235345':[ 0.434,  0.534,  0.212,  0.98 ],
                              '1234546':[ 0.534,  0.634,  0.712,  0.28 ]}
            vocab_size = 7378
            print(create_input_data(tokenizer, max_length, descriptions, photo_features, vocab_size))
    (array([[ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.434,  0.534,  0.212,  0.98 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ],
           [ 0.534,  0.634,  0.712,  0.28 ]]),
    array([[  0,   0,   0,   0,   0,   2],
           [  0,   0,   0,   0,   2,  59],
           [  0,   0,   0,   2,  59, 254],
           [  0,   0,   2,  59, 254,   6],
           [  0,   2,  59, 254,   6, 134],
           [  0,   0,   0,   0,   0,   2],
           [  0,   0,   0,   0,   2,  26],
           [  0,   0,   0,   2,  26, 254],
           [  0,   0,   2,  26, 254,   6],
           [  0,   2,  26, 254,   6, 134],
           [  0,   0,   0,   0,   0,   2],
           [  0,   0,   0,   0,   2,  59],
           [  0,   0,   0,   2,  59,  16],
           [  0,   0,   2,  59,  16,  82],
           [  0,   2,  59,  16,  82,  24],
           [  0,   0,   0,   0,   0,   2],
           [  0,   0,   0,   0,   2,  59],
           [  0,   0,   0,   2,  59,  16],
           [  0,   0,   2,  59,  16, 165],
           [  0,   2,  59,  16, 165, 127],
           [  2,  59,  16, 165, 127,  24]]),
    array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
           [ 0.,  0.,  0., ...,  0.,  0.,  0.],
           [ 0.,  0.,  0., ...,  0.,  0.,  0.],
           ...,
           [ 0.,  0.,  0., ...,  0.,  0.,  0.],
           [ 0.,  0.,  0., ...,  0.,  0.,  0.],
           [ 0.,  0.,  0., ...,  0.,  0.,  0.]]))
        """
        pass
    


    查看原文:https://upcwsh.top/cv/188/
  • 相关阅读:
    (8)FastDFS
    (7)文件上传
    (6)品牌新增
    数据仓库_MySQL(2)
    数据仓库_Linux(5)&MySQL(1)
    J哥说生产事故之僵尸进程
    J哥说生产事故之CPU爆表
    idea classpath
    (五)返回两个数组之间的差异
    (四)数组扁平化
  • 原文地址:https://www.cnblogs.com/pteromyini/p/12366649.html
Copyright © 2020-2023  润新知