keras merged model

本文介绍了一种使用Keras框架实现的手写数字识别系统。该系统通过合并三个不同分支的卷积神经网络来提高识别准确性。每个分支针对输入图像的不同特征进行训练,最终通过全连接层整合所有特征进行分类。

keras merged model
可参考网址
http://www.cnblogs.com/qianboping/p/6509794.html
https://www.kaggle.com/nikosias/keras-merged-model

import numpy as np
import pandas as pd

from keras.optimizers import SGD
from keras.models import Sequential
from keras.layers import Merge
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.layers.core import Dense, Activation, Dropout, Reshape, Flatten
from keras.utils.np_utils import to_categorical

data = pd.read_csv('../input/train.csv')
images = data.iloc[:,1:].values
images = images.astype(np.float)
images = np.multiply(images, 1.0 / 255.0)
print ('Train\'s shape =>({0[0]},{0[1]})'.format(images.shape))

labelsFlat = data[[0]].values
classes = len(np.unique(labelsFlat))
labelsCategorical = to_categorical(labelsFlat,classes)
labelsCategorical = labelsCategorical.astype(np.uint8)
print ('Train\'s classes =>({0})'.format(classes))

test = pd.read_csv('../input/test.csv').values
testX = test
testX = testX.astype(np.float)
testX = np.multiply(testX, 1.0 / 255.0)
print ('Test\'s shape =>({0[0]},{0[1]})'.format(testX.shape))

leftBranch = Sequential()
leftBranch.add(Reshape((1,28,28), input_shape=(784,)))
leftBranch.add(Convolution2D(classes, 3, 1, activation='relu'))
leftBranch.add(MaxPooling2D((2, 2), strides=(2, 2)))
leftBranch.add(Flatten())

rightBranch = Sequential()
rightBranch.add(Reshape((1,28,28), input_shape=(784,)))
rightBranch.add(Convolution2D(classes, 1, 3, activation='relu'))
rightBranch.add(MaxPooling2D((2, 2), strides=(2, 2)))
rightBranch.add(Flatten())

centralBranch = Sequential()
centralBranch.add(Reshape((1,28,28), input_shape=(784,)))
centralBranch.add(Convolution2D(classes, 5, 5, activation='relu'))
centralBranch.add(MaxPooling2D((2, 2), strides=(2, 2)))
centralBranch.add(Flatten())

merged = Merge([leftBranch, centralBranch, rightBranch], mode='concat')

model = Sequential()
model.add(merged)
model.add(Dense(28*3, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(28, activation='relu'))
model.add(Dense(input_dim=10, output_dim=classes))
model.add(Activation("softmax"))

sgd = SGD(lr=0.5, momentum=0.0, decay=0.0, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
model.fit([images,images,images], labelsCategorical,
            nb_epoch=5, batch_size=100, verbose=2)

yPred = model.predict_classes([testX,testX,testX])

np.savetxt('dr.csv', np.c_[range(1,len(yPred)+1),yPred], delimiter=',',
            header = 'ImageId,Label', comments = '', fmt='%d')
### 解决 Keras 自定义双输入模型中 `model.build` 的 TensorShape 错误 在使用 Keras 构建具有多个输入的自定义模型时,调用 `model.build(input_shape)` 是常见的操作。然而,在处理多输入的情况下,容易遇到类似于单输入场景中的形状转换错误。以下是针对此类问题的具体分析与解决方案。 #### 1. 错误原因剖析 - **复合输入形状管理不当** 当模型接受两个或更多输入时,`build()` 方法需要接收一个列表形式的输入形状参数,其中每个元素对应单一输入的形状描述。如果传入了不符合规范的数据结构(如字典而非列表),则会引发解析异常[^3]。 - **动态张量初始化不足** 对于某些复杂架构而言,仅仅提供静态形状信息不足以满足内部机制的要求;特别是那些涉及条件分支或者循环控制流的部分,往往还需要额外的支持材料来辅助完成完整的拓扑搭建过程[^4]。 #### 2. 解决策略 为了妥善解决上述提到的问题,可以采取以下措施之一: ##### (1)正确设置多重输入形状 当面对拥有两路独立信道作为入口端口的情况时,应该向 `build()` 提供形似 `[shape_a, shape_b]` 这样的数组对象,而不是单独的一个整体范围说明。例如: ```python input_shapes = [(28, 28, 1), (20,)] # 假设有图像数据加上一些特征数值 model.build(input_shapes) ``` 这里分别指定了第一个输入为灰度图片样式(高度宽度均为28像素,通道数唯一),第二个则是长度固定为20的一维向量集合[^3]。 ##### (2)利用 Input 层预先声明接口规格 另一种推荐做法是在实际执行 `build()` 操作之前,就借助 `tf.keras.Input` 明确指出各个路径所期望接纳的内容特性。之后再依据这些预设好的占位符继续往下扩展其余组成部分即可。示范代码如下所示: ```python from tensorflow import keras encoder_input = keras.Input(shape=(28, 28, 1), name="encoder_input") decoder_input = keras.Input(shape=(20,), name="decoder_input") # 定义后续逻辑... merged_output = ... model = keras.Model(inputs=[encoder_input, decoder_input], outputs=merged_output) model.compile(optimizer='adam', loss='mse') ``` 如此一来便无需手动干预底层细节层面的东西,同时也规避掉了因人为失误而导致的各种隐患[^3]。 ##### (3)延迟至首次前馈过程中自动推断 最后还有一种折衷办法可供选择——那就是干脆省略掉显式的 `build()` 调用环节,而是等到真正开始喂送真实样例进去的时候才让系统自行决定一切必要的准备工作。像下面这样简单粗暴地启动训练周期就行啦: ```python X_enc = np.random.rand(100, 28, 28, 1).astype('float32') X_dec = np.random.rand(100, 20).astype('float32') y_true = ... history = model.fit([X_enc, X_dec], y_true, epochs=5, batch_size=16) ``` 尽管这种方法看似便捷高效,但实际上却隐藏着不少潜在风险因素在里面,尤其是在大规模分布式环境下更是如此[^4]。 --- ### 总结 综上所述,通过精确设定匹配目标网络结构特性的输入配置方式,辅以适当层次上的抽象封装技巧运用,完全可以克服由 `model.build` 所带来的各类麻烦困扰。与此同时也要注意权衡利弊得失关系,在追求简洁优雅的同时兼顾稳定性可靠性等方面考量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值