深度学习第四周学习

目录

一、MobileNet_V1

1.1Depthwise Convolution(DW卷积)

1.2超参数

 二、MobileNet_V2

2.1Inverted Residuals

 2.2Linear Bottlenecks

 三、MobileNet_V3

1、更新Block

3.1.1加入SE模块(通道注意机制)

3.1.2重新设计激活函数

2、重新设计耗时层结构 

3、MobileNet_V3网络结构​

三、SEnet

四、代码学习:HybridSN对高光图谱分类

1、三维卷积

2、HybridSN对高光图谱分类

4.2.1代码实现

4.2.2 输出结果


一、MobileNet_V1

       传统卷积神经网络内存需求大,运算量大,无法在移动设备及嵌入式设备上运行。MobileNet网络是由google团队在2017年提出的,专注于移动端或者嵌入式设备中的轻量级CNN网络。相比传统卷积神经网络,在准确率小幅降低的前提下大大减少模型参数与运算量。(相比VGG16准确率减少了0.9%, 但模型参数只有VGG1/32。

网络亮点:1、Depthwise Convolution。2、增加超参数\alpha\beta

1.1Depthwise Convolution(DW卷积)

传统卷积卷积核的通道数=输入特征矩阵的通道数,输出特征矩阵的通道数=卷积核的个数。

DW卷积卷积核的通道数为1,输入特征矩阵的通道数=卷积核的个数=输出特征矩阵的通道数

1.2超参数 \alpha ,\beta

\alpha是指用来控制卷积核个数的倍率,\beta是指输入图像的分辨率。下图是MobileNet_V1的网络结构,表6、7分别是不同卷积核个数、不同图像分辨率下网络模型在ImageNet数据集的准确率,计算量和模型参数量。表8是MobileNet_V1网络与其他网络的对比,它在准确率没有下降太多的情况下大大减少的模型参数量和计算量。

 二、MobileNet_V2

MobileNet v2 网络是由 google 团队在 2018 年提出的,相比 MobileNet V1 网 络,准确率更高,模型更小。
网络亮点:Inverted Residuals(倒残差结构),Linear Bottlenecks

2.1Inverted Residuals

传统的残差结构类似一个中间窄两头宽的瓶颈结构,而倒残差结构则反之,它先升维再降维。

并且倒残差结构使用RELU6(x)作为激活函数。原因是实验表明当输出矩阵的维数较低时,relu函数将丢失原始输入的多数特征(这种情况在高维情况得以缓解),到残差结构的输出维数较低,因此使用RELU6(x)。RELU6(x)函数图像如下。

 2.2Linear Bottlenecks

下图左边是两种倒残差结构的示意图,右边给出了中间处理过程中特征图尺寸的变化。当stride=1且输入特征矩阵与输出特征矩阵shape相同时才进行相加操作。 

 MobileNet_V2的网络结构如下图所示:

三、MobileNet_V3

1、更新Block

3.1.1加入SE模块(通道注意机制)

SE模块将特征矩阵的每一个通道进行一个池化处理,第一个全连接输出节点个数为输入节点个数的1/4。第二个全连接层输出节点再恢复为原来的数量。得到每个通道的权重,将每个通道与对应权重按元素相乘。

3.1.2重新设计激活函数

 sigmoid函数无论是计算还是求导都比较复杂,对移动设备不友好,因此使用hard-swish进行替代。

2、重新设计耗时层结构 

1、减少第一个卷积层卷积核的个数(32->16),2、精简了Last Stage。在几乎没有降低准确率的情况下大大减少了计算时间。

3、MobileNet_V3网络结构

四、SEnet

在MoboleNet_V3中提到SE模块。它由SEnet演变而来。卷积核作为卷积神经网络的核心,通常被看做是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述。为了学习一个性能强劲的网络,研究人员提出从空间维度层面提升网络性能,如inception(聚合多种感受野上的特征),inside-outside Network。 

SENet则通过考虑通道之间的关系增强网络性能,他包括Squeeze和Excitation两个操作,故命名为SENet,他通过三个操作重标定前面得到的特征。Squeeze:将每一个通道压缩为一个实数,这个实数某种程度上代表整个通道。Excitation:他为每个特征通道生成权重,用来显示地建模通道间的相关性。Reweight:将第二步输出的权重看做每个特征通道的重要性,通过乘法逐通道加权到先前特征上,完成在通道维度上的重标定。

将SENet应用到inceotion和ResNet:在左图中,使用global average pooling 作为Squeeze 操作。紧接着两个Fully Connected 层组成一个Bottleneck结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的1/16 ,然后经过ReLu激活后再通过一个Fully Connected 层升回到原来的维度。 这样做比直接用一个Fully Connected 层的好处在于:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)极大地减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重,最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。在右图中:在Addition前对分支上Residual的特征进行了特征重标定。如果对Addition后主支上的特征进行重标定,由于在主干上存在0~1的scale操作,在网络较深BP优化时就会在靠近输入层容易出现梯度消散的情况,导致模型难以优化。

目前大多数的主流网络都是基于这两种类似的单元通过repeat方式叠加来构造的。由此可见,SE 模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的building block 单元中嵌入SE模块,我们可以获得不同种类的SENet。如SE-BN-Inception、SE-ResNet、SE-ReNeXt、SE-Inception-ResNet-v2等等。

五、代码学习:HybridSN对高光图谱分类

1、三维卷积

二维卷积使用的卷积核具有两个维度,

2、HybridSN对高光图谱分类

4.2.1代码实现

HybridSN网络结构如下:

class HybridSN(nn.Module):
    def __init__(self):
        super(HybridSN, self).__init__()
        self.conv1 = nn.Conv3d(1,8,(7,3,3),stride=1,padding=0)
        self.bn1 = nn.BatchNorm3d(8)
        self.conv2 = nn.Conv3d(8, 16, (5, 3, 3),stride=1,padding=0)
        self.bn2 = nn.BatchNorm3d(16)
        self.conv3 = nn.Conv3d(16, 32, (3, 3, 3),stride=1,padding=0)
        self.bn3 = nn.BatchNorm3d(32)
        self.conv4 = nn.Conv2d(576,64,(3,3),stride=1,padding=0)
        self.bn4 = nn.BatchNorm2d(64)
        self.fc1 = nn.Linear(18496, 256)
        self.fc2 = nn.Linear(256, 128)
        self.fc3 = nn.Linear(128, 16)
        self.dropout = nn.Dropout(0.4)

    def forward(self,x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = F.relu(self.bn2(self.conv2(out)))
        out = F.relu(self.bn3(self.conv3(out)))
        out = F.relu(self.bn4(self.conv4(out.reshape(out.shape[0],-1,19,19))))
        out = out.reshape(out.shape[0], -1)
        out = F.relu(self.dropout(self.fc1(out)))
        out = F.relu(self.dropout(self.fc2(out)))
        out = self.fc3(out)



        # out = nn.Softmax(out)
        return out

 数据处理部分:

# 对高光谱数据 X 应用 PCA 变换
def applyPCA(X, numComponents):
    newX = np.reshape(X, (-1, X.shape[2]))
    pca = PCA(n_components=numComponents, whiten=True)
    newX = pca.fit_transform(newX)
    newX = np.reshape(newX, (X.shape[0], X.shape[1], numComponents))
    return newX

# 对单个像素周围提取 patch 时,边缘像素就无法取了,因此,给这部分像素进行 padding 操作
def padWithZeros(X, margin=2):
    newX = np.zeros((X.shape[0] + 2 * margin, X.shape[1] + 2* margin, X.shape[2]))
    x_offset = margin
    y_offset = margin
    newX[x_offset:X.shape[0] + x_offset, y_offset:X.shape[1] + y_offset, :] = X
    return newX

# 在每个像素周围提取 patch ,然后创建成符合 keras 处理的格式
def createImageCubes(X, y, windowSize=5, removeZeroLabels = True):
    # 给 X 做 padding
    margin = int((windowSize - 1) / 2)
    zeroPaddedX = padWithZeros(X, margin=margin)
    # split patches
    patchesData = np.zeros((X.shape[0] * X.shape[1], windowSize, windowSize, X.shape[2]))
    patchesLabels = np.zeros((X.shape[0] * X.shape[1]))
    patchIndex = 0
    for r in range(margin, zeroPaddedX.shape[0] - margin):
        for c in range(margin, zeroPaddedX.shape[1] - margin):
            patch = zeroPaddedX[r - margin:r + margin + 1, c - margin:c + margin + 1]
            patchesData[patchIndex, :, :, :] = patch
            patchesLabels[patchIndex] = y[r-margin, c-margin]
            patchIndex = patchIndex + 1
    if removeZeroLabels:
        patchesData = patchesData[patchesLabels>0,:,:,:]
        patchesLabels = patchesLabels[patchesLabels>0]
        patchesLabels -= 1
    return patchesData, patchesLabels

def splitTrainTestSet(X, y, testRatio, randomState=345):
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=testRatio, random_state=randomState, stratify=y)
    return X_train, X_test, y_train, y_test
class_num = 16
X = sio.loadmat('Indian_pines_corrected.mat')['indian_pines_corrected']
y = sio.loadmat('Indian_pines_gt.mat')['indian_pines_gt']

# 用于测试样本的比例
test_ratio = 0.90
# 每个像素周围提取 patch 的尺寸
patch_size = 25
# 使用 PCA 降维,得到主成分的数量
pca_components = 30

print('Hyperspectral data shape: ', X.shape)
print('Label shape: ', y.shape)

print('\n... ... PCA tranformation ... ...')
X_pca = applyPCA(X, numComponents=pca_components)
print('Data shape after PCA: ', X_pca.shape)

print('\n... ... create data cubes ... ...')
X_pca, y = createImageCubes(X_pca, y, windowSize=patch_size)
print('Data cube X shape: ', X_pca.shape)
print('Data cube y shape: ', y.shape)

print('\n... ... create train & test data ... ...')
Xtrain, Xtest, ytrain, ytest = splitTrainTestSet(X_pca, y, test_ratio)
print('Xtrain shape: ', Xtrain.shape)
print('Xtest  shape: ', Xtest.shape)

# 改变 Xtrain, Ytrain 的形状,以符合 keras 的要求
Xtrain = Xtrain.reshape(-1, patch_size, patch_size, pca_components, 1)
Xtest  = Xtest.reshape(-1, patch_size, patch_size, pca_components, 1)
print('before transpose: Xtrain shape: ', Xtrain.shape)
print('before transpose: Xtest  shape: ', Xtest.shape)

# 为了适应 pytorch 结构,数据要做 transpose
Xtrain = Xtrain.transpose(0, 4, 3, 1, 2)
Xtest  = Xtest.transpose(0, 4, 3, 1, 2)
print('after transpose: Xtrain shape: ', Xtrain.shape)
print('after transpose: Xtest  shape: ', Xtest.shape)
""" Training dataset"""
class TrainDS(torch.utils.data.Dataset):
    def __init__(self):
        self.len = Xtrain.shape[0]
        self.x_data = torch.FloatTensor(Xtrain)
        self.y_data = torch.LongTensor(ytrain)
    def __getitem__(self, index):
        # 根据索引返回数据和对应的标签
        return self.x_data[index], self.y_data[index]
    def __len__(self):
        # 返回文件数据的数目
        return self.len

""" Testing dataset"""
class TestDS(torch.utils.data.Dataset):
    def __init__(self):
        self.len = Xtest.shape[0]
        self.x_data = torch.FloatTensor(Xtest)
        self.y_data = torch.LongTensor(ytest)
    def __getitem__(self, index):
        # 根据索引返回数据和对应的标签
        return self.x_data[index], self.y_data[index]
    def __len__(self):
        # 返回文件数据的数目
        return self.len

# 创建 trainloader 和 testloader
trainset = TrainDS()
testset  = TestDS()
train_loader = torch.utils.data.DataLoader(dataset=trainset, batch_size=128, shuffle=True, num_workers=0)
test_loader  = torch.utils.data.DataLoader(dataset=testset,  batch_size=128, shuffle=False, num_workers=0)

训练与测试:

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 网络放到GPU上
net = HybridSN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

# 开始训练
total_loss = 0
for epoch in range(100):
    for i, (inputs, labels) in enumerate(train_loader):
        inputs = inputs.to(device)
        labels = labels.to(device)
        # 优化器梯度归零
        optimizer.zero_grad()
        # 正向传播 + 反向传播 + 优化
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print('[Epoch: %d]   [loss avg: %.4f]   [current loss: %.4f]' %(epoch + 1, total_loss/(epoch+1), loss.item()))

print('Finished Training')
torch.save(net.state_dict(),'HybridSN.pt')
count = 0
# 模型测试
# 模型测试
HybridSN_state_dict = torch.load('HybridSN.pt')
testnet = HybridSN().to(device)
testnet.load_state_dict(HybridSN_state_dict)
for inputs, _ in test_loader:
    inputs = inputs.to(device)
    outputs = testnet(inputs)
    outputs = np.argmax(outputs.detach().cpu().numpy(), axis=1)
    if count == 0:
        y_pred_test =  outputs
        count = 1
    else:
        y_pred_test = np.concatenate( (y_pred_test, outputs) )

# 生成分类报告
classification = classification_report(ytest, y_pred_test, digits=4)
print(classification)

4.2.2 输出结果

训练:

[Epoch: 1]   [loss avg: 19.3299]   [current loss: 1.8529]
[Epoch: 2]   [loss avg: 16.0378]   [current loss: 1.2326]
[Epoch: 3]   [loss avg: 13.6405]   [current loss: 0.8591]
[Epoch: 4]   [loss avg: 11.7273]   [current loss: 0.6772]
[Epoch: 5]   [loss avg: 10.1480]   [current loss: 0.4938]
[Epoch: 6]   [loss avg: 8.8922]   [current loss: 0.2869]
[Epoch: 7]   [loss avg: 7.9382]   [current loss: 0.1645]
[Epoch: 8]   [loss avg: 7.1212]   [current loss: 0.1203]
[Epoch: 9]   [loss avg: 6.4553]   [current loss: 0.1149]
[Epoch: 10]   [loss avg: 5.9022]   [current loss: 0.0984]
[Epoch: 11]   [loss avg: 5.4493]   [current loss: 0.1192]
[Epoch: 12]   [loss avg: 5.0607]   [current loss: 0.0952]
[Epoch: 13]   [loss avg: 4.7175]   [current loss: 0.1009]
[Epoch: 14]   [loss avg: 4.4220]   [current loss: 0.0767]
[Epoch: 15]   [loss avg: 4.1617]   [current loss: 0.0624]
[Epoch: 16]   [loss avg: 3.9322]   [current loss: 0.1154]
[Epoch: 17]   [loss avg: 3.7302]   [current loss: 0.0124]
[Epoch: 18]   [loss avg: 3.5399]   [current loss: 0.0207]
[Epoch: 19]   [loss avg: 3.3711]   [current loss: 0.0271]
[Epoch: 20]   [loss avg: 3.2155]   [current loss: 0.0230]
[Epoch: 21]   [loss avg: 3.0704]   [current loss: 0.0045]
[Epoch: 22]   [loss avg: 2.9402]   [current loss: 0.0091]
[Epoch: 23]   [loss avg: 2.8223]   [current loss: 0.0324]
[Epoch: 24]   [loss avg: 2.7110]   [current loss: 0.0069]
[Epoch: 25]   [loss avg: 2.6087]   [current loss: 0.0196]
[Epoch: 26]   [loss avg: 2.5176]   [current loss: 0.0595]
[Epoch: 27]   [loss avg: 2.4318]   [current loss: 0.0166]
[Epoch: 28]   [loss avg: 2.3507]   [current loss: 0.0196]
[Epoch: 29]   [loss avg: 2.2806]   [current loss: 0.0124]
[Epoch: 30]   [loss avg: 2.2132]   [current loss: 0.0204]
[Epoch: 31]   [loss avg: 2.1464]   [current loss: 0.0265]
[Epoch: 32]   [loss avg: 2.0839]   [current loss: 0.0036]
[Epoch: 33]   [loss avg: 2.0244]   [current loss: 0.0036]
[Epoch: 34]   [loss avg: 1.9697]   [current loss: 0.0082]
[Epoch: 35]   [loss avg: 1.9171]   [current loss: 0.0286]
[Epoch: 36]   [loss avg: 1.8684]   [current loss: 0.0060]
[Epoch: 37]   [loss avg: 1.8219]   [current loss: 0.0031]
[Epoch: 38]   [loss avg: 1.7758]   [current loss: 0.0205]
[Epoch: 39]   [loss avg: 1.7348]   [current loss: 0.0063]
[Epoch: 40]   [loss avg: 1.6945]   [current loss: 0.0287]
[Epoch: 41]   [loss avg: 1.6579]   [current loss: 0.1047]
[Epoch: 42]   [loss avg: 1.6263]   [current loss: 0.0431]
[Epoch: 43]   [loss avg: 1.5985]   [current loss: 0.0107]
[Epoch: 44]   [loss avg: 1.5718]   [current loss: 0.0518]
[Epoch: 45]   [loss avg: 1.5451]   [current loss: 0.1146]
[Epoch: 46]   [loss avg: 1.5176]   [current loss: 0.0402]
[Epoch: 47]   [loss avg: 1.4882]   [current loss: 0.0018]
[Epoch: 48]   [loss avg: 1.4621]   [current loss: 0.0067]
[Epoch: 49]   [loss avg: 1.4347]   [current loss: 0.0059]
[Epoch: 50]   [loss avg: 1.4090]   [current loss: 0.0041]
[Epoch: 51]   [loss avg: 1.3857]   [current loss: 0.0150]
[Epoch: 52]   [loss avg: 1.3629]   [current loss: 0.0107]
[Epoch: 53]   [loss avg: 1.3393]   [current loss: 0.0037]
[Epoch: 54]   [loss avg: 1.3174]   [current loss: 0.0688]
[Epoch: 55]   [loss avg: 1.2970]   [current loss: 0.0791]
[Epoch: 56]   [loss avg: 1.2753]   [current loss: 0.0028]
[Epoch: 57]   [loss avg: 1.2576]   [current loss: 0.0069]
[Epoch: 58]   [loss avg: 1.2381]   [current loss: 0.0035]
[Epoch: 59]   [loss avg: 1.2224]   [current loss: 0.1436]
[Epoch: 60]   [loss avg: 1.2043]   [current loss: 0.0024]
[Epoch: 61]   [loss avg: 1.1866]   [current loss: 0.0133]
[Epoch: 62]   [loss avg: 1.1679]   [current loss: 0.0059]
[Epoch: 63]   [loss avg: 1.1514]   [current loss: 0.0150]
[Epoch: 64]   [loss avg: 1.1341]   [current loss: 0.0026]
[Epoch: 65]   [loss avg: 1.1176]   [current loss: 0.0012]
[Epoch: 66]   [loss avg: 1.1026]   [current loss: 0.0035]
[Epoch: 67]   [loss avg: 1.0889]   [current loss: 0.0428]
[Epoch: 68]   [loss avg: 1.0757]   [current loss: 0.0060]
[Epoch: 69]   [loss avg: 1.0627]   [current loss: 0.0008]
[Epoch: 70]   [loss avg: 1.0489]   [current loss: 0.0033]
[Epoch: 71]   [loss avg: 1.0356]   [current loss: 0.0104]
[Epoch: 72]   [loss avg: 1.0228]   [current loss: 0.0268]
[Epoch: 73]   [loss avg: 1.0118]   [current loss: 0.0532]
[Epoch: 74]   [loss avg: 0.9995]   [current loss: 0.0066]
[Epoch: 75]   [loss avg: 0.9882]   [current loss: 0.0190]
[Epoch: 76]   [loss avg: 0.9770]   [current loss: 0.0333]
[Epoch: 77]   [loss avg: 0.9651]   [current loss: 0.0051]
[Epoch: 78]   [loss avg: 0.9538]   [current loss: 0.0162]
[Epoch: 79]   [loss avg: 0.9419]   [current loss: 0.0051]
[Epoch: 80]   [loss avg: 0.9318]   [current loss: 0.0010]
[Epoch: 81]   [loss avg: 0.9213]   [current loss: 0.0033]
[Epoch: 82]   [loss avg: 0.9119]   [current loss: 0.0002]
[Epoch: 83]   [loss avg: 0.9017]   [current loss: 0.0001]
[Epoch: 84]   [loss avg: 0.8917]   [current loss: 0.0023]
[Epoch: 85]   [loss avg: 0.8814]   [current loss: 0.0008]
[Epoch: 86]   [loss avg: 0.8718]   [current loss: 0.0351]
[Epoch: 87]   [loss avg: 0.8623]   [current loss: 0.0029]
[Epoch: 88]   [loss avg: 0.8529]   [current loss: 0.0001]
[Epoch: 89]   [loss avg: 0.8444]   [current loss: 0.0012]
[Epoch: 90]   [loss avg: 0.8356]   [current loss: 0.0207]
[Epoch: 91]   [loss avg: 0.8268]   [current loss: 0.0049]
[Epoch: 92]   [loss avg: 0.8188]   [current loss: 0.0341]
[Epoch: 93]   [loss avg: 0.8103]   [current loss: 0.0003]
[Epoch: 94]   [loss avg: 0.8034]   [current loss: 0.0649]
[Epoch: 95]   [loss avg: 0.7954]   [current loss: 0.0030]
[Epoch: 96]   [loss avg: 0.7899]   [current loss: 0.0001]
[Epoch: 97]   [loss avg: 0.7840]   [current loss: 0.0128]
[Epoch: 98]   [loss avg: 0.7774]   [current loss: 0.0258]
[Epoch: 99]   [loss avg: 0.7708]   [current loss: 0.0018]
[Epoch: 100]   [loss avg: 0.7670]   [current loss: 0.0180]
Finished Training

训练完成后保存模型,用该模型对测试数据集进行多次,对比结果。
              precision    recall  f1-score   support

         0.0     0.9737    0.9024    0.9367        41
         1.0     0.9886    0.9416    0.9645      1285
         2.0     0.9381    0.9933    0.9649       747
         3.0     0.9581    0.9671    0.9626       213
         4.0     0.9769    0.9724    0.9747       435
         5.0     0.9686    0.9863    0.9774       657
         6.0     0.8929    1.0000    0.9434        25
         7.0     0.9977    0.9907    0.9942       430
         8.0     0.8125    0.7222    0.7647        18
         9.0     0.9720    0.9509    0.9613       875
        10.0     0.9705    0.9814    0.9759      2210
        11.0     0.9554    0.9625    0.9590       534
        12.0     0.9891    0.9784    0.9837       185
        13.0     0.9903    0.9903    0.9903      1139
        14.0     0.9857    0.9914    0.9885       347
        15.0     0.8810    0.8810    0.8810        84

    accuracy                         0.9726      9225
   macro avg     0.9532    0.9508    0.9514      9225
weighted avg     0.9729    0.9726    0.9725      9225

precision    recall  f1-score   support

         0.0     0.6452    0.9756    0.7767        41
         1.0     0.9876    0.9268    0.9562      1285
         2.0     0.9783    0.9652    0.9717       747
         3.0     0.9758    0.9484    0.9619       213
         4.0     0.9643    0.9931    0.9785       435
         5.0     0.9490    0.9909    0.9695       657
         6.0     1.0000    0.9600    0.9796        25
         7.0     1.0000    0.9930    0.9965       430
         8.0     0.7391    0.9444    0.8293        18
         9.0     0.9403    0.9714    0.9556       875
        10.0     0.9707    0.9760    0.9734      2210
        11.0     0.9713    0.9494    0.9602       534
        12.0     0.9888    0.9514    0.9697       185
        13.0     0.9861    0.9939    0.9899      1139
        14.0     0.9713    0.9769    0.9741       347
        15.0     0.8537    0.8333    0.8434        84

    accuracy                         0.9687      9225
   macro avg     0.9326    0.9594    0.9429      9225
weighted avg     0.9699    0.9687    0.9689      9225

可以看到两次测试的准确率并不一样,原因是每次随机选择90%的数据集作为测试集,故每次测试的数据都不一样。

可以通过适当提高训练数据集的规模提高分类准确率。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值