我想制作一个手工特征融合cnn深度网络的宝石分类模型,发现各种融合之后效果没有得到提升,准确率在15轮的时候基本就停在78%-80%,怎么办!是否有方法优化这种特征融合!
#这是混合模型,把cnn提取的特征和手动提取的特征相融合,融合时用了动态加权。
class HybridGemClassifier(nn.Module):
def __init__(self, hand_feat_dim):
super().__init__()
# 深度特征提取器
self.cnn = models.mobilenet_v2(pretrained=True)
self.cnn_feat = nn.Sequential(
*list(self.cnn.children())[:-1],
nn.AdaptiveAvgPool2d((1,1)),
nn.Flatten()
)
# 手工特征处理
self.hand_fc = nn.Sequential(
nn.Linear(hand_feat_dim, 128),
nn.BatchNorm1d(128),
nn.ReLU(inplace=True)
)
# 动态特征加权
self.attention = nn.Sequential(
nn.Linear(1280 + 128, 64),
nn.ReLU(inplace=True),
nn.Linear(64, 2),
nn.Softmax(dim=1)
)
# 分类器
self.classifier = nn.Sequential(
nn.Linear(1280 + 128, 512),
nn.BatchNorm1d(512),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(512, Config.num_classes)
)
# 深度特征和手工特征权重
self.weights_w_cnn = 0
self.weights_w_hand = 0
def forward(self, img, hand_feat):
# 深度特征
cnn_feat = self.cnn_feat(img)
# 手工特征
hand_feat = self.hand_fc(hand_feat)
# 动态加权
combined = torch.cat([cnn_feat, hand_feat], dim=1)
weights = self.attention(combined)
self.weights_w_cnn = weights[:, 0].mean()
self.weights_w_hand = weights[:, 1].mean()
weighted_cnn = cnn_feat * weights[:, 0].unsqueeze(1)
weighted_hand = hand_feat * weights[:, 1].unsqueeze(1)
# 特征融合
fused = torch.cat([weighted_cnn, weighted_hand], dim=1)
return self.classifier(fused)
#这是特征提取的函数,提取了图片的颜色,纹理,边缘密度信息。
def extract_handcrafted(self, img):
# 颜色特征 (HSV直方图)
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
hist_hsv = cv2.calcHist([hsv], [0, 1, 2], None,
[8, 8, 8], [0, 180, 0, 256, 0, 256])
hist_hsv = cv2.normalize(hist_hsv, None).flatten()
# 纹理特征 (LBP)
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
lbp = local_binary_pattern(gray, 8, 1, method='uniform')
hist_lbp, _ = np.histogram(lbp, bins=np.arange(0, 10), density=True)
# 结构特征 (边缘密度)
edges = cv2.Canny(gray, 100, 200)
edge_density = np.sum(edges) / (img.size / 3)
return np.concatenate([hist_hsv, hist_lbp, [edge_density]]).astype(np.float32)