作者 | Dipanjan(DJ)Sarkar

来源 | Medium

编辑 | 代码医生团队

介绍

人工智能(AI)不再仅限于研究论文和学术界。业内不同领域的企业和组织正在构建由AI支持的大规模应用程序。这里要考虑的问题是,“我们是否相信AI模型做出的决策?”和“机器学习或深度学习模型如何做出决策?”。解释机器学习或深度学习模型一直是整个数据科学生命周期中经常被忽视的任务,因为数据科学家或机器学习工程师会更多地参与实际推动生产或建立和运行模型。

但是除非正在构建一个有趣的机器学习模型,否则准确性并不是唯一重要的!业务利益相关者和消费者经常会问到用于解决现实问题的任何机器学习模型的公平性,问责制和透明度等难题!

现在有可解释的人工智能(XAI)的整个研究分支!

在本文中,将研究用于解释计算机视觉中使用的深度学习模型的概念,技术和工具,更具体地说 - 卷积神经网络(CNN)。将采用实践方法,使用Keras和TensorFlow 2.0实现深度学习模型,并利用开源工具来解释这些模型所做出的决策!简而言之本文的目的是找出 - 深度学习模型真正看到了什么?

卷积神经网络

用于计算机视觉问题的最流行的深度学习模型是卷积神经网络(CNN)!

资料来源:Becomehuman.ai

CNN通常由多个卷积和池化层组成,这有助于深度学习模型从图像等可视数据中自动提取相关特征。由于这种多层架构,CNN学习了强大的特征层次结构,即空间,旋转和平移不变。

CNN模型中的关键操作如上图所示。任何图像都可以表示为像素值的张量。卷积层有助于从该图像中提取特征(形成特征图)。网络中的较浅层(更接近输入数据)学习非常通用的特征,如边缘,角落等。网络中更深的层(更靠近输出层)学习与输入图像有关的非常具体的特征。下图有助于总结任何CNN模型的关键方面。

由于只关心CNN模型如何感知图像,因此不会从头开始训练任何CNN模型。相反将在示例中利用迁移学习的功能和预先训练的CNN模型。

像VGG-16这样的预训练模型已经在具有大量不同图像类别的大型数据集(ImageNet)上进行了预训练。考虑到这一事实,该模型应该已经学习了强大的功能层次结构。因此该模型已经学习了属于1,000个不同类别的超过一百万个图像的特征的良好表示,可以作为适合于计算机视觉问题的新图像的良好特征提取器。

解读CNN模型 - 深度学习模型真正看到了什么?

这是有趣的部分,真的可以通过一个看似黑盒子的CNN模型来解除呈现的不透明度,并尝试理解幕后真正发生的事情以及模型在看到图像时真正看到了什么?有许多技术和工具可用于解释基于视觉的深度学习模型所做出的决策。本文中介绍的一些主要技术如下所示。

看看这些技术中的每一种,并解释一些使用Keras和TensorFlow构建的基于CNN的深度学习模型。

SHAP Gradient Explainer

这种技术试图结合来自Integrated Gradients,SHapley Additive exPlanations(SHAP)和SmoothGrad的众多想法。该技术试图使用预期梯度(集成梯度的扩展)来解释模型决策。这是一种功能归因方法,专为基于Shapley值扩展到无限玩家游戏的可微模型而设计。将在此处使用此框架来实现此技术。

https://github.com/slundberg/shap

集成梯度值与SHAP值略有不同,需要单个参考值进行集成。然而在SHAP Gradient Explainer中,预期梯度将积分重新表示为期望,并将该期望与来自背景数据集的采样参考值相结合。因此该技术使用整个数据集作为背景分布而不是单个参考值。尝试在一些示例图像上实现这一点。首先加载一些基本依赖项和模型可视化函数实用程序。

import kerasfrom keras.applications.vgg16 import VGG16from keras.applications.vgg16 import preprocess_input, decode_predictionsfrom matplotlib.colors import LinearSegmentedColormapimport numpy as npimport shapimport keras.backend as Kimport json shap.initjs()  # utility function to visualize SHAP values in larger image formats# this modifies the `shap.image_plot(...)` functiondef visualize_model_decisions(shap_values, x, labels=None, figsize=(20, 30)):        colors = []    for l in np.linspace(1, 0, 100):        colors.append((30./255, 136./255, 229./255,l))    for l in np.linspace(0, 1, 100):        colors.append((255./255, 13./255, 87./255,l))    red_transparent_blue = LinearSegmentedColormap.from_list("red_transparent_blue", colors)     multi_output = True    if type(shap_values) != list:        multi_output = False        shap_values = [shap_values]     # make sure labels    if labels is not None:        assert labels.shape[0] == shap_values[0].shape[0], "Labels must have same row count as shap_values arrays!"        if multi_output:            assert labels.shape[1] == len(shap_values), "Labels must have a column for each output in shap_values!"        else:            assert len(labels.shape) == 1, "Labels must be a vector for single output shap_values."     # plot our explanations    fig_size = figsize    fig, axes = plt.subplots(nrows=x.shape[0], ncols=len(shap_values) + 1, figsize=fig_size)    if len(axes.shape) == 1:        axes = axes.reshape(1,axes.size)    for row in range(x.shape[0]):        x_curr = x[row].copy()         # make sure        if len(x_curr.shape) == 3 and x_curr.shape[2] == 1:            x_curr = x_curr.reshape(x_curr.shape[:2])        if x_curr.max() > 1:            x_curr /= 255.                axes[row,0].imshow(x_curr)        axes[row,0].axis('off')                # get a grayscale version of the image        if len(x_curr.shape) == 3 and x_curr.shape[2] == 3:            x_curr_gray = (0.2989 * x_curr[:,:,0] + 0.5870 * x_curr[:,:,1] + 0.1140 * x_curr[:,:,2]) # rgb to gray        else:            x_curr_gray = x_curr         if len(shap_values[0][row].shape) == 2:            abs_vals = np.stack([np.abs(shap_values[i]) for i in range(len(shap_values))], 0).flatten()        else:            abs_vals = np.stack([np.abs(shap_values[i].sum(-1)) for i in range(len(shap_values))], 0).flatten()        max_val = np.nanpercentile(abs_vals, 99.9)        for i in range(len(shap_values)):            if labels is not None:                axes[row,i+1].set_title(labels[row,i])            sv = shap_values[i][row] if len(shap_values[i][row].shape) == 2 else shap_values[i][row].sum(-1)            axes[row,i+1].imshow(x_curr_gray, cmap=plt.get_cmap('gray'), alpha=0.15, extent=(-1, sv.shape[0], sv.shape[1], -1))            im = axes[row,i+1].imshow(sv, cmap=red_transparent_blue, vmin=-max_val, vmax=max_val)            axes[row,i+1].axis('off')            cb = fig.colorbar(im, ax=np.ravel(axes).tolist(), label="SHAP value", orientation="horizontal", aspect=fig_size[0]/0.2)    cb.outline.set_visible(False)

下一步是加载预先训练好的VGG-16模型,该模型先前已在Imagenet数据集上进行过训练。可以使用以下代码轻松完成。

model = VGG16(weights='imagenet', include_top=True)model.summary() # output_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================input_3 (InputLayer)         (None, 224, 224, 3)       0         _________________________________________________________________block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      _________________________________________________________________block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     _________________________________________________________________block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         _________________________________________________________________......_________________________________________________________________fc2 (Dense)                  (None, 4096)              16781312  _________________________________________________________________predictions (Dense)          (None, 1000)              4097000   =================================================================Total params: 138,357,544Trainable params: 138,357,544Non-trainable params: 0_________________________________________________________________

加载CNN模型后,现在将加载一个可用作背景分布的小图像数据集,将使用四个样本图像进行模型解释。

# load sample imagesX, y = shap.datasets.imagenet50() # load sample cat image for testIMAGE_PATH = './cat2.jpg'img = keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(224, 224))img = keras.preprocessing.image.img_to_array(img) # select 3 other sample images for testimport matplotlib.pyplot as plt%matplotlib inline to_predict = np.array([X[28], X[35], X[46], img])fig, ax = plt.subplots(1, 4, figsize=(18, 10))ax[0].imshow(to_predict[0]/255.)ax[1].imshow(to_predict[1]/255.)ax[2].imshow(to_predict[2]/255.)ax[3].imshow(to_predict[3]/255.)

有四种不同类型的图像,包括一只猫的照片!首先看一下模型对这些图像的预测。

# get imagenet id to label name mappingsurl = "https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json"fname = shap.datasets.cache(url)with open(fname) as f:    class_names = json.load(f)    # make model predictionspredictions = model.predict(preprocess_input(to_predict.copy())) # get prediction labelspredicted_labels = [class_names.get(str(pred)) for pred in np.argmax(predictions, axis=1)]print(predicted_labels)

[['n02999410','chain'],

['n01622779','great_grey_owl'],

['n03180011','desktop_computer'],

['n02124075','Egyptian_cat']]

首先尝试可视化模型在神经网络的第7层(通常是模型中较浅层之一)中看到的内容。

# utility function to pass inputs to specific model layersdef map2layer(x, layer):    feed_dict = dict(zip([model.layers[0].input], [preprocess_input(x.copy())]))    return K.get_session().run(model.layers[layer].input, feed_dict)    # focus on the 7th layer of CNN modelprint(model.layers[7].input)Out [46]: <tf.Tensor 'block2_pool_2/MaxPool:0' shape=(?, 56, 56, 128) dtype=float32> # make model predictionse = shap.GradientExplainer((model.layers[7].input, model.layers[-1].output),                            map2layer(preprocess_input(X.copy()), 7))shap_values, indexes = e.shap_values(map2layer(to_predict, 7), ranked_outputs=2)index_names = np.vectorize(lambda x: class_names[str(x)][1])(indexes)print(index_names)Out [47]: array([['chain', 'chain_mail'],                 ['great_grey_owl', 'prairie_chicken'],                 ['desktop_computer', 'screen'],                 ['Egyptian_cat', 'tabby']], dtype=') # visualize model decisionsvisualize_model_decisions(shap_values=shap_values, x=to_predict,                          labels=index_names, figsize=(20, 40))

这提供了一个很好的视角,可以看到模型对每个图像做出的前两个预测,以及为什么要做出这样的决定。来看看VGG-16模型中的一个更深层,并可视化第14层的决策。

# focus on 14th layer of the CNN modelprint(model.layers[14].input)Out [49]: <tf.Tensor 'block4_conv3_2/Relu:0' shape=(?, 28, 28, 512) dtype=float32> # make model predictionse = shap.GradientExplainer((model.layers[14].input, model.layers[-1].output),                            map2layer(preprocess_input(X.copy()), 14))shap_values, indexes = e.shap_values(map2layer(to_predict, 14), ranked_outputs=2)index_names = np.vectorize(lambda x: class_names[str(x)][1])(indexes) # visualize model decisionsvisualize_model_decisions(shap_values=shap_values, x=to_predict,                          labels=index_names, figsize=(20, 40))

现在可以看到模型变得更强大和更自信的预测判决基础上,十八值的强度,模型预测一个方面screen对一个desktop_computer地方,它还要在键盘上。预测猫是tabby因为鼻子,胡须,面部图案等特定功能!

解释使用TensorFlow 2.0构建的CNN模型

对于其余四种技术,将使用TensorFlow 2.0预先训练的模型,并使用流行的开源框架tf-explain。这里的想法是研究CNN的不同模型解释技术。

https://github.com/sicara/tf-explain

加载预先训练的CNN模型

加载一个最复杂的预训练CNN模型,Xception模型声称比Inception V3模型略胜一筹。从加载必要的依赖项和预先训练的模型开始。

# load dependenciesimport numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltfrom tf_explain.core.activations import ExtractActivationsfrom tensorflow.keras.applications.xception import decode_predictions %matplotlib inline # load Xception pre-trained CNN modelmodel = tf.keras.applications.xception.Xception(weights='imagenet',                                                include_top=True)model.summary() # OutputModel: "xception"__________________________________________________________________________________________________Layer (type)                    Output Shape         Param #     Connected to                     ==================================================================================================input_1 (InputLayer)            [(None, 299, 299, 3) 0                                            __________________________________________________________________________________________________block1_conv1 (Conv2D)           (None, 149, 149, 32) 864         input_1[0][0]                    __________________________________________________________________________________________________block1_conv1_bn (BatchNormaliza (None, 149, 149, 32) 128         block1_conv1[0][0]               __________________________________________________________________________________________________......__________________________________________________________________________________________________block14_sepconv2_act (Activatio (None, 10, 10, 2048) 0           block14_sepconv2_bn[0][0]        __________________________________________________________________________________________________avg_pool (GlobalAveragePooling2 (None, 2048)         0           block14_sepconv2_act[0][0]       __________________________________________________________________________________________________predictions (Dense)             (None, 1000)         2049000     avg_pool[0][0]                   ==================================================================================================Total params: 22,910,480Trainable params: 22,855,952Non-trainable params: 54,528

可以从上面的模型体系结构快照中看到,该模型总共有14个块,每个块中有多个层。绝对是CNN更深的模型之一!

样本图像的模型预测

将重用猫的样本图像,并使用Xception模型进行前5个预测。在进行预测之前先加载图像。

# load and pre-process cat imageIMAGE_PATH = './cat2.jpg'img = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(299, 299))img = tf.keras.preprocessing.image.img_to_array(img) # view the imageplt.imshow(img/255.)

现在使用Xception模型对此图像进行前5个预测。将在推断之前预处理图像。

# load imagenet id to class label mappingsimport requests response = requests.get('https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json')imgnet_map = response.json()imgnet_map = {v[1]: k for k, v in imgnet_map.items()} # make model predictionsimg = tf.keras.applications.xception.preprocess_input(img)predictions = model.predict(np.array([img]))decode_predictions(predictions, top=5)

[[('n02124075', 'Egyptian_cat', 0.80723596),

  ('n02123159', 'tiger_cat', 0.09508163),

  ('n02123045', 'tabby', 0.042587988),

  ('n02127052', 'lynx', 0.00547999),

  ('n02971356', 'carton', 0.0014547487)]]

有趣的预测,至少前三名肯定是相关的!

激活层可视化

此技术通常用于可视化给定输入如何来自特定激活层。关键的想法是探索在模型中激活哪些特征图并将其可视化。通常这是通过查看每个特定层来完成的。以下代码展示了CNN模型的块2中的一个层的激活层可视化。

explainer = ExtractActivations()grid = explainer.explain((np.array([img]), None), model, ['block2_sepconv2_act'])fig, ax = plt.subplots(figsize=(18, 18))ax.imshow(grid, cmap='binary_r')

这种方式了解哪些特征图被激活以及它们通常关注的图像部分。

遮挡敏感度

使用遮挡灵敏度进行解释的想法非常直观。基本上试图通过迭代地遮挡(隐藏)部分来可视化图像的各部分如何影响神经网络模型的置信度。这是通过用灰色方块系统地遮挡输入图像的不同部分并监视分类器的输出来完成的。

# get label imagenet IDimgnet_map['Egyptian_cat'] from tf_explain.core.occlusion_sensitivity import OcclusionSensitivity explainer = OcclusionSensitivity()img_inp = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(299, 299))img_inp = tf.keras.preprocessing.image.img_to_array(img_inp)grid = explainer.explain(([img_inp], None), model, 285, 7)fig, ax = plt.subplots(figsize=(8, 8))plt.imshow(grid)

理想情况下,图像的特定色块应以红色\黄色突出显示,如热图,但对于猫图像,它会突出显示红色色调的整体图像,原因可能是因为猫的缩放图像。然而,图像的左侧具有更高的强度,更多地关注猫的形状,而不是图像的纹理。

GradCAM

这可能是解释CNN模型最流行和最有效的方法之一。使用GradCAM,尝试通过查看类激活图(CAM)来可视化图像的各部分如何影响神经网络的输出。类激活图是一种简单的技术,用于获取CNN使用的辨别图像区域来识别图像中的特定类。换句话说,类激活图(CAM)可以看到图像中的哪些区域与此类相关。

  • grad-CAM的输出将是有助于目标函数最大化的像素。例如,如果对最大化类别编号285的内容感兴趣,则将所有其他类别归零。

  • 相对于卷积层输出计算目标函数的梯度。这可以通过反向传播有效地完成

给定图像和感兴趣的类别(例如,“老虎猫”或任何其他类型的可微分输出)作为输入,通过模型的CNN部分向前传播图像,然后通过任务特定的计算获得原始分数对于该类别。除了所需的类(虎猫)之外,所有类的梯度都设置为零,设置为1.然后将该信号反向传播到感兴趣的整流卷积特征图,将它们组合起来计算粗Grad-CAM定位( blue heatmap)表示模型必须在哪里做出特定决定。

看一下CNN模型中特定块的GradCAM可视化。首先从块1(较浅层)可视化其中一个层。

from tf_explain.core.grad_cam import GradCAM explainer = GradCAM() # get imagenet IDs for cat breedsimgnet_map['tabby'], imgnet_map['Egyptian_cat']Out [24]: ('281', '285') # visualize GradCAM outputs in Block 1grid1 = explainer.explain(([img], None), model, 'block1_conv2', 281)grid2 = explainer.explain(([img], None), model, 'block1_conv2', 285) fig = plt.figure(figsize = (18, 8))ax1 = fig.add_subplot(1, 3, 1)ax1.imshow(img_inp / 255.)ax1.imshow(grid1, alpha=0.6)ax2 = fig.add_subplot(1, 3, 2)ax2.imshow(img_inp / 255.)ax2.imshow(grid2, alpha=0.6)ax3 = fig.add_subplot(1, 3, 3)ax3.imshow(img_inp / 255.)

就像预期的那样,这是浅层之一,看到更高级别的特征,如边缘和角落在网络中被激活。现在在块6中可视化来自网络中较深层之一的GradCAM输出。

# visualize GradCAM output from Block 6grid1 = explainer.explain(([img], None), model, 'block6_sepconv1', 281)grid2 = explainer.explain(([img], None), model, 'block6_sepconv1', 285) fig = plt.figure(figsize = (18, 8))ax1 = fig.add_subplot(1, 3, 1)ax1.imshow(img_inp / 255.)ax1.imshow(grid1, alpha=0.6)ax2 = fig.add_subplot(1, 3, 2)ax2.imshow(img_inp / 255.)ax2.imshow(grid2, alpha=0.6)ax3 = fig.add_subplot(1, 3, 3)ax3.imshow(img_inp / 255.)

事情肯定开始变得更有趣,可以清楚地看到,当模型预测猫时tabby,它关注的是纹理以及猫的整体形状和结构,而不是它预测猫作为一个Egyptian_cat。最后来看看Block 14中模型中最深的一层。

# visualize GradCAM output from Block 14grid1 = explainer.explain(([img], None), model, 'block14_sepconv1', 281)grid2 = explainer.explain(([img], None), model, 'block14_sepconv1', 285) fig = plt.figure(figsize = (18, 8))ax1 = fig.add_subplot(1, 3, 1)ax1.imshow(img_inp / 255.)ax1.imshow(grid1, alpha=0.6)ax2 = fig.add_subplot(1, 3, 2)ax2.imshow(img_inp / 255.)ax2.imshow(grid2, alpha=0.6)ax3 = fig.add_subplot(1, 3, 3)ax3.imshow(img_inp / 255.)

非常有趣的是,对于tabby猫标签预测,该模型还在观察猫周围的区域,该区域主要关注猫的整体形状\结构以及猫的面部结构的某些方面!

SmoothGrad

这种技术有助于在决策输入上可视化稳定的梯度。关键目标是识别强烈影响最终决策的像素。该策略的起点是类别得分函数相对于输入图像的梯度。该梯度可以解释为灵敏度图,并且有几种技术可以阐述这个基本思想。

SmoothGrad是一种简单的方法,可以帮助在视觉上锐化基于梯度的灵敏度图。核心思想是拍摄感兴趣的图像,通过向图像添加噪声来对相似图像进行采样,然后获取每个采样图像的最终灵敏度图的平均值。

from tf_explain.core.smoothgrad import SmoothGrad explainer = SmoothGrad() grid1 = explainer.explain(([img], None), model, 281, 80, .2)grid2 = explainer.explain(([img], None), model, 285, 80, .2) fig = plt.figure(figsize = (18, 8))ax1 = fig.add_subplot(1, 3, 1)ax1.imshow(img_inp / 255.)ax1.imshow(grid1, alpha=0.9, cmap='binary_r')ax2 = fig.add_subplot(1, 3, 2)ax2.imshow(img_inp / 255.)ax2.imshow(grid2, alpha=0.9, cmap='binary_r')ax3 = fig.add_subplot(1, 3, 3)ax3.imshow(img_inp / 255.)

对于tabby猫来说,焦点肯定是在脸上的关键点,包括斑点和条纹,这是非常有区别的特征。

结论

这应该很好地了解如何利用预先训练的复杂CNN模型来预测新图像,甚至尝试可视化神经网络模型真正看到的内容!这里的技术列表并不详尽,但绝对涵盖了一些最流行和广泛使用的解释CNN模型的方法。建议您使用自己的数据和模型进行尝试!

本文中使用的所有代码都可以在GitHub中作为Jupyter笔记本在此存储库中获得。

https://github.com/dipanjanS/data_science_for_all/tree/master/gde_cnn_interpretation_xai

推荐阅读

在Python中逐步检测Canny边缘 - 计算机视觉

深度学习模型保存_解读计算机视觉的深度学习模型相关推荐

  1. 3月3 pytorch模型保存的.pt, .pth, .pkl的pytorch模型文件,只是后缀不同而已(仅此而已),打开方式

    pytorch模型保存的格式 首先讲讲保存模型或权重参数的后缀格式,权重参数和模型参数的后缀格式一样,pytorch中最常见的模型保存使用 .pt 或者是 .pth 作为模型文件扩展名.还有其他的保存 ...

  2. 飞桨模型保存_史上最全解读 | 飞桨模型库重大升级 主流算法模型全覆盖

    11 月 5 日,在 Wave Summit+2019 深度学习开发者峰会上,飞桨全新发布和重要升级了最新的 21 项进展,在深度学习开发者社区引起了巨大的反响. 很多未到场的开发者觉得遗憾,希望可以 ...

  3. 飞桨模型保存_飞桨对话模型工具箱(二):对话自动评估模块ADE

    1. 对话自动评估 随着对话系统的不断发展和成熟,如何评价对话系统的回复质量,成为了一个新的研究方向. 对话自动评估技术,能够帮助企业或个人快速评估对话系统的回复质量,减少人工评估成本,具有重要的商业 ...

  4. 深度学习求深度图_关于图的深度学习成功挑战和下一步

    深度学习求深度图 重点 (Top highlight) 图神经网络的下一步是什么? (What is next in store for graph neural networks?) TL;DR T ...

  5. python深度学习include框架_用Python实现深度学习框架

    1.大咖推荐:复旦大学计算机学院教授邱锡鹏.品质科技创始人兼CEO袁进辉(@老师木).格灵深瞳创始人兼CEO赵勇.奇虎360集团副总裁邓亚峰联合推荐 2.干货满满:从零开始用Python实现自己的深度 ...

  6. 飞桨模型保存_手把手教你用飞桨做词向量模型 SkipGram

    飞桨开发者说成员:肥猫.忆臻 在做 NLP 的任务时,一个非常 basic 的操作就是如何编码自然语言中的符号,例如词.短语,甚至词缀.目前流行的方法有大约三种: •  特征工程:这类方法依赖于手工特 ...

  7. adams如何保存_教你如何快速把模型 从solidworks转到adams里

    怎么样把模型从solid work转到adams里面 关于solidworks模型导入adams中的详细步骤 首先在sw的装配体中,利用装配关系,将原点位置和坐标轴方向弄成理想的坐标系,因为导入ada ...

  8. Tensorflow 2.x(keras)源码详解之第十章:keras中的模型保存与加载(详解Checkpointmd5模型序列化)

      大家好,我是爱编程的喵喵.双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中.从事机器学习以及相关的前后端开发工作.曾在阿里云.科大讯飞.CCF等比赛获得多次Top名次.现 ...

  9. python线性回归模型预处理_线性回归-2 数据预处理与模型验证评估

    主要内容数据向量化处理 特征放缩 上采样和下采样 重采样和交叉验证 模型验证 python 代码实现 1. 数据向量化处理 对于给定的m个样本,假设最终的拟合函数是 为拟合的权重系数,则有 损失函数改 ...

最新文章

  1. 这所高校招收佛学研究生,面试需要写论文,毕业后安排去向,就业前景好!...
  2. Linux源代码编译安装详解
  3. 出国留学想申请国家留学基金委的奖学金?传说中的csc! 从这里入手就对了!
  4. python网络编程——IO多路复用之epoll
  5. 5最后一条记录_在一堆数据中,如何获取最后一次记录?
  6. Excel@C#.Net之单元格设置相关
  7. [软件] 装机员 Ghost Win7 Sp1 32位纯净10月版
  8. 行测:判断推理之图形推理
  9. android蓝牙hid 鼠标,BLE HID协议-----蓝牙鼠标代码流分析
  10. jzojNOIP2014模拟 8.14总结
  11. 虚拟机安装centeros7镜像
  12. 单片机——神奇的中断嵌套实验
  13. GVINS文章暴力翻译(仅供自学)
  14. 宛如一个未来穿越者,终年33岁的印度数学天才,大数学家哈代说“他发现并创造了数学”
  15. 什么是堆漏洞挖掘?堆的glibc实现、Arena(main_arena、thread_arena)
  16. Oracle Sequence创建与使用
  17. 【半导体先进工艺制程技术系列】FinFET和UTB-SOI简介
  18. 程序员的私人外包专家
  19. 祝母亲身体健康,节日快乐
  20. 【JAVAFX 构建中国地图2021最新版】

热门文章

  1. Android中asset文件夹和raw文件夹区别(转载)
  2. CCNA综合实验配置
  3. [C语言] 文件操作,解压华为官方固件UNDATE.APP工具(源代码);
  4. 如何将PPT转换成手机APP
  5. Maven生命周期详解
  6. 第十一章 异常,日志,断言和调试
  7. 【Linux原理】Linux中硬链接和软链接的区别和联系
  8. Linux TCP 连接数修改
  9. [转]卓越科技回应所谓的最牛,最受歧视的招聘
  10. web service方法进行全文检索_SpringMVC(Web应用)配置教程终章项目实战