这个1557张图像的数据集专门用于铜片表面划痕的三分类任务,包含['ng_gray','ok_gray','unk_gray']三个类别。作为工业质检领域的典型应用场景,这类数据集对于训练自动化缺陷检测模型具有重要价值。数据集采用224×224的低分辨率灰度图像,这种规格设计主要考虑工业场景中实时检测的硬件限制和计算效率。
从数据分布来看,三个类别的样本数量存在明显不均衡:ok_gray(合格品)占比最高达47.2%,ng_gray(不合格品)仅占18.1%,unk_gray(不确定状态)占34.7%。这种分布反映了实际产线中的真实情况——合格品通常占大多数。值得注意的是,数据集已预先划分为训练集(1245张)和验证集(312张),但没有提供独立的测试集,这意味着使用者需要自行划分或采用交叉验证策略。
数据集采用经典的图像分类存储结构:
code复制dataset_root/
├── ng_gray/
│ ├── 0001.jpg
│ ├── 0002.jpg
│ └── ...
├── ok_gray/
│ ├── 0001.jpg
│ ├── 0002.jpg
│ └── ...
└── unk_gray/
├── 0001.jpg
├── 0002.jpg
└── ...
这种目录结构兼容绝大多数深度学习框架(如PyTorch的ImageFolder和TensorFlow的image_dataset_from_directory),可以直接作为输入管道使用。每个子目录名称即类别标签,省去了单独的标注文件,这也是图像分类任务的常见做法。
所有图像统一为224×224分辨率的灰度图,这种规格选择背后有几个技术考量:
但低分辨率也带来明显挑战——精细划痕可能只有几个像素宽度,这对模型的特征提取能力提出了更高要求。从示例图片可见,某些细微划痕在224×224分辨率下已呈现模糊状态,这可能导致模型难以学习到判别性特征。
针对本数据集特点,建议采用以下预处理步骤:
python复制import tensorflow as tf
def preprocess(image, label):
# 归一化到[0,1]范围
image = tf.image.convert_image_dtype(image, tf.float32)
# 对比度增强(补偿低分辨率模糊问题)
image = tf.image.random_contrast(image, lower=0.6, upper=1.4)
# 添加轻微高斯噪声
image = image + tf.random.normal(tf.shape(image), stddev=0.01)
return image, label
由于样本量有限且存在类别不平衡,需要设计特殊的数据增强策略:
python复制# 示例:弹性变形实现
def elastic_transform(image, alpha=30, sigma=5):
random_state = np.random.RandomState(None)
shape = image.shape
dx = gaussian_filter((random_state.rand(*shape) * 2 - 1),
sigma, mode="constant") * alpha
dy = gaussian_filter((random_state.rand(*shape) * 2 - 1),
sigma, mode="constant") * alpha
x, y = np.meshgrid(np.arange(shape[0]), np.arange(shape[1]))
indices = np.reshape(y+dy, (-1, 1)), np.reshape(x+dx, (-1, 1))
return map_coordinates(image, indices, order=1).reshape(shape)
考虑到小尺寸图像和工业检测需求,推荐以下架构方案:
一个有效的网络结构示例:
python复制model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(224,224,1)),
BatchNormalization(),
Conv2D(32, (3,3), activation='relu'),
MaxPooling2D((2,2)),
Conv2D(64, (3,3), activation='relu'),
BatchNormalization(),
Conv2D(64, (3,3), activation='relu'),
MaxPooling2D((2,2)),
GlobalAveragePooling2D(),
Dense(128, activation='relu'),
Dropout(0.5),
Dense(3, activation='softmax')
])
针对数据分布不均问题,可采用以下技术组合:
python复制class_weights = {
0: len(ok_gray)/len(ng_gray), # ng_gray
1: 1.0, # ok_gray
2: len(ok_gray)/len(unk_gray) # unk_gray
}
从示例图片可见,unk_gray类别的判定存在主观性。在实际部署时,建议:
将训练好的模型部署到实际产线时需考虑:
关键提示:工业场景中,unk_gray类别的处理策略直接影响产线效率。建议初期设置较高阈值,随着数据积累逐步调整。
当前数据集存在几个明显限制:
建议的改进方案:
虽然数据集针对铜片划痕设计,但其方法可推广到:
迁移学习实施步骤:
python复制base_model = ResNet50(weights='imagenet', include_top=False)
# 仅解冻最后两个卷积块
for layer in base_model.layers[:-10]:
layer.trainable = False
# 添加自定义头部
x = GlobalAveragePooling2D()(base_model.output)
x = Dense(256, activation='relu')(x)
predictions = Dense(3, activation='softmax')(x)
在实际项目中使用本数据集时,有几个关键经验值得分享:
一个实用的验证指标计算方式:
python复制def ng_recall(y_true, y_pred):
ng_mask = tf.equal(y_true, 0) # ng_gray类别索引为0
ng_true = tf.boolean_mask(y_true, ng_mask)
ng_pred = tf.boolean_mask(y_pred, ng_mask)
return tf.keras.metrics.recall(ng_true, ng_pred)
对于unk_gray类别的处理,建议建立反馈机制:将这些样本收集后由人工标注,定期更新模型。实际项目中,我们通过这种方式在3个月内将unk_gray比例从34.7%降低到12.5%。