使用Python将图像数据写入到MNIST格式以方便各个DL框架之间的训练

本文详细介绍了MNIST数据集的文件格式,并提供了一种使用Python将自定义数据集转换为MNIST格式的方法。该方法适用于灰度图像数据,通过具体的Python代码示例展示了如何创建符合MNIST标准的训练图像集和标签文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近使用各种不同的深度学习框架测试他们之间的性能和好坏,由于每个框架上手时间都比较短,没有足够的时间了解他们载入自定义格式数据的方法。由于深度学习界的Hello World 几乎就是使用CNN 训练 Mnist 手写数字。所以各个框架都几乎支持可以直接读取Mnist文件。所以把训练直接写入到MNIST格式,是一种很好的偷懒方法。不过如果不修改数据接口只能读取灰度图像。

我们先来看一下MNIST的数据格式。Lecun爸爸的主页就有。

TRAINING SET LABEL FILE (train-labels-idx1-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  60000            number of items 
0008     unsigned byte   ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.

TRAINING SET IMAGE FILE (train-images-idx3-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000803(2051) magic number 
0004     32 bit integer  60000            number of images 
0008     32 bit integer  28               number of rows 
0012     32 bit integer  28               number of columns 
0016     unsigned byte   ??               pixel 
0017     unsigned byte   ??               pixel 
........ 
xxxx     unsigned byte   ??               pixel

Label File

  • 先是一个32位的整形 表示的是Magic Number,这是用来标示文件格式的用的。一般默认不变。2049
  • 第二是图片的的数量
  • 接下去就是一次排列图片的标示Label。
  • -

Image File

  • 也是Magic Number。同上。保持不变2051.
  • 图片的数量
  • 图片的高
  • 图片的宽
  • 图片的像素点[灰度 256位]。

实现过程

这种在C++/C 上实现似乎很简单。在Python下可以用Struct来处理二进制。可以看一下这篇博文



def writeMnist(data,rows,cols, path_images = "imt_mnist_training_set.data",path_labels="imt_mnist_training_labels.data"):

"""
@输入格式
@data [imgs(浮点/字节),labels]
@rows 高度
@cols 宽度
@path_images 训练图像集文件路径
@path_labels label文件路径
"""
    _set,_labels = data;

    model = 0;
    print _set[0].dtype;

    if(len(_set[0])>0 and type(_set[0]) == float):
        model = 1;
    magic_nums_trainning = 2051;
    magic_nums_labels = 2049;

    num_training = len(_set);
    header_images = [magic_nums_trainning,num_training,rows,cols];
    header_labels = [magic_nums_labels,num_training];
    len_img = rows*cols;

    header_images_format = '>IIII';
    header_labels_format = '>II';

    len_img_format = '>'+str(len_img)+'B'

    buffer_training_set = create_string_buffer(4*4 + len_img*num_training);
    buffer_training_labels = create_string_buffer(2*4  +  num_training);
    offset = 0 ;

    struct.pack_into(header_images_format,buffer_training_set,offset,*header_images);
    offset += struct.calcsize(header_images_format);
    print(len_img_format)
    for i in range(num_training):
        if(model == 1):
            byte_type = np.array(_set[i])*255
            byte_type = byte_type.astype(np.uint8).ravel();
        else:
            byte_type = _set[i].ravel();
        struct.pack_into(len_img_format,buffer_training_set,offset,*byte_type);
        offset += struct.calcsize(len_img_format);

    file_training_set = open(path_images,'wb');
    file_training_set.write(buffer_training_set);
    offset =  0 ;
    struct.pack_into(header_labels_format,buffer_training_labels,offset,*header_labels);
    offset += struct.calcsize(header_labels_format);
    for i in range(num_training):
        struct.pack_into(">B",buffer_training_labels,offset,_labels[i]);
        offset += struct.calcsize(">B")
    file_training_label = open(path_labels,'wb');
    file_training_label.write(buffer_training_labels);
<think>我们正在处理一个关于KNIME Keras成中的错误:DataLoadError,具体是缺少Dense层和端口对象规格无效(Invalid spec class DLKerasUnmaterializedNetworkPortObjectSpec)。这个错误通常发生在尝试加载Keras模型时,模型结构或端口对象与预期不符。 ### 问题分析 1. **MISSING Dense Layer**:这个错误表明模型加载时找不到一个或多个Dense层。可能原因包括: - 模型保存时使用了自定义层(如Dense),但在加载时没有提供自定义对象的定义。 - 模型结构在保存和加载之间发生了变化,例如层名称被更改或删除。 2. **Invalid spec class DLKerasUnmaterializedNetworkPortObjectSpec**:这个错误与KNIME的端口对象规范有关。在KNIME中,节点之间通过端口传递数据,每个端口都有预期的数据规范(spec)。此错误表明传入端口的数据规范不符合节点的预期。具体地,`DLKerasUnmaterializedNetworkPortObjectSpec`通常表示一个未完全初始化的Keras网络端口对象,可能发生在模型未正确加载或传递时。 ### 解决步骤 #### 步骤1: 确保模型保存正确 - 如果你是自己训练的模型并保存,请确保保存时包含了模型结构(通常使用`model.save()`保存为HDF5格式或SavedModel格式,这样会同时保存模型结构和权重)。 - 如果模型包含自定义层(例如自定义的Dense层),在保存时应该通过`custom_objects`参数提供这些层的定义,以便在加载时能够识别。 #### 步骤2: 在KNIME中正确加载Keras模型 在KNIME中,通常使用“Keras Network Reader”节点来加载Keras模型。确保: - 模型路径正确。 - 如果模型是HDF5格式(.h5文件),选择正确的文件。 - 如果模型包含自定义层,需要在“Keras Network Reader”节点的设置中提供自定义层的定义(通过“Custom Layers”选项)。 #### 步骤3: 检查端口连接 - 在KNIME工作流中,确保模型加载节点的输出正确连接到后续节点(如“Keras Network Executor”)。 - 错误信息中提到的`DLKerasUnmaterializedNetworkPortObjectSpec`通常表示模型没有成功加载,因此后续节点接收到的端口对象是未初始化的。请检查“Keras Network Reader”节点是否成功执行(节点状态应为绿色)。 #### 步骤4: 验证模型结构 - 如果可能,在Python中(例如使用Keras)加载模型,验证模型结构是否正确。例如: ```python from keras.models import load_model model = load_model('your_model.h5') model.summary() ``` 如果模型包含自定义层,需要在`load_model`中通过`custom_objects`参数指定。 #### 步骤5: 重新生成端口对象 如果上述步骤都正确,但问题仍然存在,可以尝试在KNIME中重新创建端口对象: - 删除当前加载模型的节点,重新添加并配置“Keras Network Reader”节点。 - 确保KNIME的Keras成版本与模型训练使用的Keras版本兼容。 ### 示例KNIME工作流修复 假设你的工作流如下: 1. **Keras Network Reader**:加载模型。 2. **Keras Network Executor**:执行模型进行预测。 修复步骤: - 双击“Keras Network Reader”节点,检查模型路径和自定义层设置。 - 如果没有自定义层,确保“Custom Layers”选项为空。 - 运行“Keras Network Reader”节点单独执行,查看是否有错误。 - 如果节点执行成功,检查其输出端口的数据规范(右键节点 -> 输出端口视图)。应该看到`DLKerasNetworkPortObjectSpec`,而不是`DLKerasUnmaterializedNetworkPortObjectSpec`。 ### 注意事项 - KNIME的Keras成依赖于后端的Keras/TensorFlow版本。确保KNIME中配置的Keras版本与模型训练时的版本一致。 - 如果模型是在TensorFlow 2.x中保存的,确保KNIME使用的是支持TF 2.x的Keras成扩展。 §§相关问题§§ 1. 如何在KNIME中定义自定义Keras层? 2. KNIME中Keras模型加载的常见错误有哪些? 3. 如何检查KNIME节点的端口规范? 4. KNIME的Keras成支持哪些模型格式?</think>### KNIME Keras DataLoadError 解决方案 您在KNIME中遇到的`DataLoadError`包含两个关键问题: 1. **MISSING Dense Layer**:模型加载时无法识别Dense层 2. **Invalid spec class DLKerasUnmaterializedNetworkPortObjectSpec**:端口对象规格不匹配 以下是系统化的解决步骤: --- ### 一、解决 MISSING Dense Layer 错误 #### 原因分析 - 模型包含自定义层或未正确注册标准层 - Keras/TensorFlow版本不兼容 - 模型保存格式问题 #### 解决步骤: 1. **显式注册自定义层** 在Keras Network Reader节点的配置中: - 打开"Custom Layers"选项卡 - 添加缺失的Dense层定义: ```python from keras.layers import Dense ``` - 如果使用自定义层,需提供完整类定义 2. **统一版本环境** - 检查模型训练环境与KNIME的Keras成版本: - KNIME → Help → About → Installation Details - 对比`tensorflow`和`keras`版本号 - 若版本不匹配: ```mermaid graph LR A[原始训练环境] -->|导出模型| B[KNIME环境] B --> C{版本检查} C -->|不匹配| D[重训练模型或降级KNIME扩展] C -->|匹配| E[继续调试] ``` 3. **转换模型格式** - 使用`tf.keras.models.save_model(model, 'path')`保存为SavedModel格式 - 或使用HDF5格式: ```python model.save('model.h5', save_format='h5') ``` --- ### 二、解决 Invalid PortObjectSpec 错误 #### 原因分析 - 节点间端口连接不匹配 - 工作流未完整初始化模型 - 缓存数据损坏 #### 解决步骤: 1. **重建端口连接** - 删除Keras Network Reader与下游节点的连接 - 重新连接并检查端口类型: - 输入端口:需接收`.h5`或SavedModel - 输出端口:应为`DLKerasNetworkPortObjectSpec` 2. **添加Keras Network Writer/Reader对** ```mermaid graph LR A[原始模型] --> B[Keras Network Writer] B --> C[模型文件.h5] C --> D[Keras Network Reader] D --> E[下游节点] ``` 通过显式写入/读取强制规格化 3. **清除节点缓存** - 右键问题节点 → Reset - 删除工作流目录中的缓存文件(通常位于`data`子目录) --- ### 三、完整验证流程 1. 创建测试工作流: ``` Keras Network Reader → Keras Network Executor (测试数据) → PMML Predictor (验证) ``` 2. 使用MNIST示例模型验证环境 3. 逐步替换为您的实际模型 > **注意**:若使用TensorFlow 2.x模型,确保KNIME AP ≥ 4.2 且安装[DL4J Keras Integration](https://kni.me/a/3XbbyhKpTxhP0sxQ)[^1] --- ### 预防措施 1. 保存工作流时包含模型文件路径 2. 使用虚拟环境容器化Keras依赖 3. 复杂模型添加元数据注释: ```json { "keras_version": "2.4.0", "backend": "tensorflow", "custom_layers": ["CustomDense"] } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值