You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

机器学习模型仅训练数据测试有效,新图像预测错误求助

问题

我正在开发一款基于图像数据的机器学习模型,用于对3种不同类型的表面粗糙度(Type 1、Type 2、Type 3)进行分类。训练数据集包含每种粗糙度类型的5组2D图像(1024*768)和3D点云数据,总计15张图像与15组点云。下方代码在使用训练数据测试时结果正确,但测试新图像时输出错误结果,恳请技术协助:

import numpy as np
import os
import cv2
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

data = []
labels = []

# Loop through the three types of surface roughness types

for i in range(1, 4):
    type_path = f"D:\\Ph.D. IEE\\Research\\My research\\Images\\type{i}"
# Loop through the 5 images and point clouds for each type
for j in range(1, 6):
    # Read in the image and point cloud files
    image_path = os.path.join(type_path, f"{j}.png")
    point_cloud_path = os.path.join(type_path, f"{j}.csv")
    image = cv2.imread(image_path)
    point_cloud = np.loadtxt(point_cloud_path, delimiter='\t')
        # Append the image and point cloud to the data list
        data.append((image, point_cloud))
        # Append the label to the labels list
        labels.append(i)

# Convert the data and labels lists to NumPy arrays
data = np.array(data)
labels = np.array(labels)

# Split the dataset into training and testing sets
train_data, test_data, train_labels, test_labels = train_test_split(data, labels, test_size=0.2, random_state=42)

# Reshape the training and testing data
train_images = train_data[:, 0]
train_images = np.array([cv2.resize(img, (1024, 768)) for img in train_images])
train_point_clouds = train_data[:, 1]
train_labels = np.array(train_labels)

test_images = test_data[:, 0]
test_images = np.array([cv2.resize(img, (1024, 768)) for img in test_images])
test_point_clouds = test_data[:, 1]
test_labels = np.array(test_labels)

# Train a machine learning model on the training data
svm_model = SVC(kernel='linear')
svm_model.fit(train_images.reshape(-1, 1024*768*3), train_labels)

# Make a prediction on a testing image
test_image_path = "D:\\Ph.D. IEE\\Research\\My research\\Test\\t6.png"
test_image = cv2.imread(test_image_path)
test_image = cv2.resize(test_image, (1024, 768))
prediction = svm_model.predict(test_image.reshape(1, -1))[0]

# Map the prediction to the corresponding surface roughness type
if prediction == 1:
    print("The testing image falls under surface roughness type 1.")
elif prediction == 2:
    print("The testing image falls under surface roughness type 2.")
elif prediction == 3:
    print("The testing image falls under surface roughness type 3.")
else:
    print("The trained model could not predict the surface roughness. ")
解决方案

1. 修复循环缩进错误

代码中嵌套循环的缩进完全错误:外层遍历类型的for i循环没有包裹内层的for j循环,导致内层循环只会遍历最后一个类型(Type3)的5组数据,训练数据实际上只有5组而非15组,模型根本没学到前两类的特征。

修正后的循环代码:

for i in range(1, 4):
    type_path = f"D:\\Ph.D. IEE\\Research\\My research\\Images\\type{i}"
    # Loop through the 5 images and point clouds for each type
    for j in range(1, 6):
        # Read in the image and point cloud files
        image_path = os.path.join(type_path, f"{j}.png")
        point_cloud_path = os.path.join(type_path, f"{j}.csv")
        image = cv2.imread(image_path)
        point_cloud = np.loadtxt(point_cloud_path, delimiter='\t')
        # Append the image and point cloud to the data list
        data.append((image, point_cloud))
        # Append the label to the labels list
        labels.append(i)

2. 利用点云数据提升特征维度

当前模型完全忽略了点云数据,只使用了图像特征。点云包含的3D表面信息对粗糙度分类至关重要,必须将图像特征和点云特征融合后再输入模型。

处理方式示例:

  • 先提取点云的统计特征(如高度均值、方差、粗糙度参数Ra/Rz等),将其转为固定长度的向量
  • 将图像的像素特征(展平后的向量)与点云统计特征拼接,作为模型的输入特征

示例代码片段:

# 定义点云特征提取函数
def extract_point_cloud_features(pc):
    # 假设点云是N×3的数组(x,y,z),提取z方向的统计特征
    z_values = pc[:, 2]
    features = [
        np.mean(z_values),
        np.std(z_values),
        np.max(z_values) - np.min(z_values),
        np.median(z_values)
    ]
    return np.array(features)

# 训练时融合特征
train_image_features = train_images.reshape(-1, 1024*768*3)
train_pc_features = np.array([extract_point_cloud_features(pc) for pc in train_point_clouds])
train_combined_features = np.hstack([train_image_features, train_pc_features])

# 测试时同样处理
test_image_features = test_images.reshape(-1, 1024*768*3)
test_pc_features = np.array([extract_point_cloud_features(pc) for pc in test_point_clouds])
test_combined_features = np.hstack([test_image_features, test_pc_features])

# 用融合特征训练模型
svm_model.fit(train_combined_features, train_labels)

3. 解决数据量过小导致的过拟合问题

仅15组训练数据,模型很容易过拟合训练集,导致对新数据泛化能力极差。

解决方法:

  • 数据增强:对图像进行旋转、翻转、噪声添加、亮度调整等操作,扩充图像数据集;对点云可进行轻微的坐标扰动、下采样/上采样增强
  • 使用正则化:给SVM添加正则化参数,比如SVC(kernel='linear', C=0.1),C值越小正则化越强,抑制过拟合
  • 换用更适合小数据的模型:比如使用预训练的CNN模型(如ResNet、VGG)提取图像特征,再结合点云特征训练分类器,预训练模型自带的通用特征能大幅提升泛化能力

4. 统一数据预处理流程

  • 确保测试图像的预处理和训练图像完全一致:比如图像的颜色空间(当前用cv2.imread读入的是BGR,是否需要转为RGB?)、归一化操作(训练时是否对像素值做了0-1归一化?测试时也要同步做)
  • 示例:训练和测试时都添加像素归一化
# 训练图像归一化
train_images = train_images / 255.0
# 测试图像同样归一化
test_image = test_image / 255.0

5. 验证模型性能

训练后要在拆分的test_data上验证模型准确率,而不是仅用训练数据测试。添加验证代码:

# 验证模型在测试集上的表现
test_pred = svm_model.predict(test_combined_features)
accuracy = np.mean(test_pred == test_labels)
print(f"测试集准确率:{accuracy:.2f}")

内容的提问来源于stack exchange,提问作者Zlatan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:35:14