1.机器学习工作流程介绍

本文学习如何思考机器学习问题。机器学习(ML)不仅关于数学和建模,而且关于选择问题的设置,识别客户需求和长期目标。本文的组织如下:

1.通过识别关键利益相关者,选择正确的度量指标,建立机器学习问题的框架。
2.因为ML是关于数据的,将讨论与数据相关的不同挑战。
3.在解决ML问题时如何组织数据集,以确保创建的模型在新数据上表现良好。
4.如何利用不同的工具来确定模型的局限性。
在本文中,将多次使用德国交通标志识别基准(German Traffic Sign Benchmarks,GTSRB)进行练习。

2.建立问题的框架
除非你是在参加机器学习比赛,否则模型的性能很少是你唯一关心的事情。例如,在自动驾驶汽车系统中,模型的推断时间(提供预测所需的时间)也是一个重要的因素。一个每秒可以消化5个图像的模型比一个每秒只能处理一个图像的模型要好,即使第二个图像的性能更好。在这种情况下,推断时间也是选择我们的模型的一个指标。

理解数据管道(pipeline)非常重要,因为它将推动模型开发。在某些情况下,获取新数据相对容易,但对它们进行标定(例如通过关联类名)可能代价很高。在这种情况下,可能希望创建一个需要较少数据的模型,或者可以处理未标定数据的模型。

3. 确定主要利益相关者

作为一名机器学习工程师,你很少会成为自己产品的最终用户。因此,您需要确定您试图解决的问题的不同涉众。为什么?因为这将推动您的模型开发。

4.选择度量指标

每一个机器学习问题都需要它自己的度量标准,而一些度量标准,如准确性,可能适合于许多问题,需要记住错误预测的后果。考虑以下情况:当构建一个垃圾邮件分类算法,应该以很少的False Positives(假阳性/误报)为目标,因为不希望算法将一些潜在的重要邮件分类到垃圾邮件文件夹。然而,False Negative (假阴性)只是一个位于收件箱中的垃圾邮件,它可以由用户手动删除。

5.分类和目标检测指标

Precision(精确度):在分类为特定类别的元素中,做对了多少个?例如,将6张包含汉堡的图片分类,其中只有5张确实包含汉堡。精度是5/6。

召回率(Recall):正确分类的图像数量除以图像总数。例如,有40张汉堡的图片,正确地分类了其中的15张。召回率(recall)是15/40。对目标检测使用相同的精确度和召回率定义,但考虑的是每个图像中目标的实例数。

Accuracy(准确性):(仅用于分类问题)正确分类的图像数量占图像总数的比例。

6.练习1
结构

在本练习中,需要使用以下文件:

Ground truth data: data/ground_truth.json包含真实数据的标签(边界框和类)。该文件包含20个观察项,每个观察项是一个字典,带有以下字段。

{filename: str, boxes: List[List[int]], classes: List[int]}

边界框使用[x1, y1, x2, y2]格式。

预测数据data/predictions.json包含预测数据的标签(边界框和类)(可以将其视为模型的输出)。格式类似于真实数据。
最后,utils.py文件包含helper函数。其中一个check_results将验证IoU计算,另一个get_data将把真实值和预测数据加载到Python字典中。

第一部分-计算IoU
目标

在本练习的第一部分中,任务是实现一个函数,该函数计算两个边界框之间的iou。

细节
iou.py中的calculate_ious函数接受两个数组,其中包含边界框坐标作为输入。两个数组都是1x4 numpy数组。数组使用以下格式:

[x1, y1, x2, y2]

其中x1 < x2, y1 < y2。(x1, y1)为左上角的坐标,(x2, y2)为边界框右下角的坐标。

例如

iou = calculate_iou(np.array([0, 0, 100, 100]), np.array([101, 101, 200, 200]))

提示
请记住,边界框可能不相交,在这种情况下,IoU应该等于0。

通过运行python iou.py,检查实现情况。

第二部分-计算精确度/召回率
目标
要求对给定的一组预测和真实值计算精确度和召回率。使用0.5 IoU的阈值来确定一个预测是否为真。

细节

precision_recall.py中的precision_recall函数以一个IoU值组成的 ious NxM数组以及两个列表pred_classes和gt_classes作为输入,该列表包含M个预测类ids和N个真实类ids。

IoU数组包含N个真实值边界框和M个预测值边界框之间的成对IoU值,如下:

ious[x, y] = calculate_iou(groundtruth[x], predictions[y])

例如

precision, recall = precision_recall(np.array([[0.5, 0.1],[0.8, 0.1]), np.array([1, 2]), np.array([1, 0]))

提示
需要计算False Negatives的数量来计算召回率。可以使用IoU数组来查找未预测的真实值边界框。

通过运行python precision_recall.py,检查程序实现情况。
参考代码

iou.py

import numpy as npfrom utils import get_data, check_resultsdef calculate_iou(gt_bbox, pred_bbox):"""calculate iou args:- gt_bbox [array]: 1x4 single gt bbox- pred_bbox [array]: 1x4 single pred bboxreturns:- iou [float]: iou between 2 bboxes"""xmin = np.max([gt_bbox[0], pred_bbox[0]])ymin = np.max([gt_bbox[1], pred_bbox[1]])xmax = np.min([gt_bbox[2], pred_bbox[2]])ymax = np.min([gt_bbox[3], pred_bbox[3]])intersection = max(0, xmax - xmin + 1) * max(0, ymax - ymin + 1)gt_area = (gt_bbox[2] - gt_bbox[0]) * (gt_bbox[3] - gt_bbox[1])pred_area = (pred_bbox[2] - pred_bbox[0]) * (pred_bbox[3] - pred_bbox[1])union = gt_area + pred_area - intersectionreturn intersection / uniondef calculate_ious(gt_bboxes, pred_bboxes):"""calculate ious between 2 sets of bboxes args:- gt_bboxes [array]: Nx4 ground truth array- pred_bboxes [array]: Mx4 pred arrayreturns:- iou [array]: NxM array of ious"""ious = np.zeros((gt_bboxes.shape[0], pred_bboxes.shape[0]))for i, gt_bbox in enumerate(gt_bboxes):for j, pred_bbox in enumerate(pred_bboxes):ious[i,j] = calculate_iou(gt_bbox, pred_bbox)return iousif __name__ == "__main__": ground_truth, predictions = get_data()# get bboxes arrayfilename = 'segment-1231623110026745648_480_000_500_000_with_camera_labels_38.png'gt_bboxes = [g['boxes'] for g in ground_truth if g['filename'] == filename][0]gt_bboxes = np.array(gt_bboxes)pred_bboxes = [p['boxes'] for p in predictions if p['filename'] == filename][0]pred_boxes = np.array(pred_bboxes)ious = calculate_ious(gt_bboxes, pred_boxes)check_results(ious)

precision_recall.py

import numpy as npfrom iou import calculate_ious
from utils import get_datadef precision_recall(ious, gt_classes, pred_classes):"""calculate precision and recallargs:- ious [array]: NxM array of ious- gt_classes [array]: 1xN array of ground truth classes- pred_classes [array]: 1xM array of pred classesreturns:- precision [float]- recall [float]"""xs, ys = np.where(ious>0.5)# calculate true positive and true negativetps = 0fps = 0for x, y in zip(xs, ys):if gt_classes[x] == pred_classes[y]:tps += 1else:fps += 1matched_gt = len(np.unique(xs))fns = len(gt_classes) - matched_gtprecision = tps / (tps+fps)recall = tps / (tps + fns)return precision, recallif __name__ == "__main__": ground_truth, predictions = get_data()# get bboxes arrayfilename = 'segment-1231623110026745648_480_000_500_000_with_camera_labels_38.png'gt_bboxes = [g['boxes'] for g in ground_truth if g['filename'] == filename][0]gt_bboxes = np.array(gt_bboxes)gt_classes = [g['classes'] for g in ground_truth if g['filename'] == filename][0]pred_bboxes = [p['boxes'] for p in predictions if p['filename'] == filename][0]pred_boxes = np.array(pred_bboxes)pred_classes = [p['classes'] for p in predictions if p['filename'] == filename][0]ious = calculate_ious(gt_bboxes, pred_boxes)precision, recall = precision_recall(ious, gt_classes, pred_classes)print(f'Precision: {precision}')print(f'Recall: {recall}')

7.数据采集与可视化

在许多情况下,需要收集自己的数据,但在某些情况下,能够利用开放源代码数据集,例如谷歌Open Image Dataset。但是,请记住最终目标以及将在何处部署或使用算法。

由于所谓的域差(domain gap),在特定数据集上训练的算法,在另一个数据集上可能表现不佳。例如,根据特定摄像头收集的数据训练的行人检测算法,可能无法根据另一个摄像头捕获的图像准确检测行人。

8.练习2 -可视化
目的

对于本练习,需要在visualization.py中实现一个函数,在一组图像上可视化真实值边框。需要使用与每个边界框相关联的类id来显示用颜色编码的边界框。需要在一个图中显示所有数据。应该以可视化为目标,因为清晰的数据可视化对于传达信息至关重要。

细节
标签(边界框和类)的位于data/ground_truth.json文件。它包含20个观察项,每个观察项是一个字典,带有以下字段。

{filename: str, boxes: List[List[int]], classes: List[int]}

边界框使用[x1, y1, x2, y2]格式。图像(png文件)位于data/ Images文件夹中。每个相关联的图像都可以与其带文件名的标签匹配。

utils.py文件包含一个帮助函数get_data,可以导入该函数来加载真实值和预测。尽管该练习只需要真实值。

提示
可以使用matplotlib补丁来创建边框可视化。可以通过边界框添加类名来改进上述可视化。

再进一步
想想看,可以在同一幅图像上以一种清晰的方式显示真实值和预测。

参考代码

import glob
import json
import osimport matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Imagefrom utils import get_datadef viz(ground_truth):"""create a grid visualization of images with color coded bboxesargs:- ground_truth [list[dict]]: ground truth data"""paths = glob.glob('data/images/*')# mapping to access data fastergtdic = {}for gt in ground_truth:gtdic[gt['filename']] = gt# color mapping of classescolormap = {1: [1, 0, 0], 2: [0, 1, 0], 4: [0, 0, 1]}f, ax = plt.subplots(4, 5, figsize=(20, 10))for i in range(20):x = i % 4y = i % 5filename = os.path.basename(paths[i])img = Image.open(paths[i])ax[x, y].imshow(img)bboxes = gtdic[filename]['boxes']classes = gtdic[filename]['classes']for cl, bb in zip(classes, bboxes):y1, x1, y2, x2 = bbrec = Rectangle((x1, y1), x2- x1, y2-y1, facecolor='none', edgecolor=colormap[cl])ax[x, y].add_patch(rec)ax[x ,y].axis('off')plt.tight_layout()plt.show()if __name__ == "__main__": ground_truth, _ = get_data()viz(ground_truth)

9.探索性数据分析(EDA)

机器学习算法可能对域转换非常敏感。这种域转换可以发生在不同的级别:

天气/光照条件:例如,只在晴天图像上训练的算法在雨天或夜间数据时表现不佳。
传感器:一个传感器的变化或不同的处理方法会产生域转换。
环境:例如,在低强度交通数据上训练的算法在高强度交通数据上表现不佳。
广泛的探索性数据分析(EDA)是任何ML项目成功的关键。为什么?因为在此阶段,ML工程师将熟悉数据集并发现数据的任何潜在挑战。EDA是项目中如此重要的一部分,以至于ML的工程师单单在它上面要花几天的时间。对于视觉问题,它需要查看数据集中的1000个图像!
10.交叉验证

​​ML算法的目标是部署在生产环境中。例如,在最终项目中创建的目标检测算法可以直接部署在自动驾驶汽车中。但在部署这种算法之前,需要确保它在遇到的任何环境中都能表现良好。换句话说,要评估模型的推广能力。

介绍三个新概念:

过拟合:当模型不能很好地推广时
偏方差权衡:为什么很难建立一个平衡的模型
交叉验证:评估模型推广效果的一种技术
过度拟合

当一个模型过拟合时,它就失去了推广的能力。当选择的模型过于复杂,开始提取噪声而不是有意义的特征时,就会发生这种情况。例如,当一个汽车检测模型开始提取数据集中的汽车的品牌特定特征(如汽车标识)而不是更广泛的特征(车轮、形状等)时,它就是过拟合。

过拟合提出了一个非常重要的问题。如何知道模型是否能恰当地一般化?事实上,当单个数据集可用时,要知道我们创建的模型是过度拟合,还是仅仅表现良好,将是一个挑战。

现在,使用术语训练数据,来描述用于教学和创建算法的数据,并为任何新的、未曾看到的数据测试数据

偏差和方差权衡

偏差-方差权衡说明了机器学习中最重要的挑战之一。如何创建一个性能良好的模型,同时保持其推广到新的、未曾见的数据的能力?算法对这些数据的性能可以通过测试误差来量化。测试误差可以进一步分解为偏差和方差。

偏差量化了模型对训练数据的拟合质量。低偏差意味着模型在训练数据集上的错误率很低。

方差量化了模型对训练数据的敏感性。换句话说,如果用另一个训练数据集替换现在的训练数据集,那么训练错误率会发生多大的变化?较低的方差说明模型对训练数据不敏感,具有较好的推广性。

验证集和交叉验证

交叉验证是一套技术,以评估模型的推广和缓解过拟合挑战的能力。在本文中,利用验证集方法,将可用数据分成两部分:

一个训练集,用于创建算法(通常80% -90%的可用数据)
    一个验证集,用于评估(可用数据的10-20%)
以及如何利用这种方法来缓解过拟合问题。

其他交叉验证方法也存在,如LOO (Leave One Out)k-fold交叉验证,但它们不适合深度学习算法。在这里(Cross Validation)关于这两种技巧的内容。

10.TFRecord

TF记录是TensorFlow的自定义数据格式。即使它们在技术上不需要用TensorFlow训练模型,但它们可能非常有用。对于一些已经存在的TensorFlow API,需要TF Record格式来训练模型。

Waymo开放数据集vs. TensorFlow目标检测API
虽然每个文件都使用.tfrecord文件,但每个文件的结构都有差异。因此,即将到来的练习将从Waymo开放数据集取一个.tfrecord,并将其转换为TensorFlow目标检测API可用的新.tfrecord。

虽然在练习中也有链接,但需要一些资源才能更容易地做到这一点。

首先,这个存储库 (GitHub - Jossome/Waymo-open-dataset-document: The official document of the dataset is too general. There are many missing details. This document aims at making it more convenient to use the dataset.提供了一些关于Waymo开放数据集本身的额外信息。
    其次,这个TF目标检测API(用于从.xml转换为.tfrecord)的教程 (Training Custom Object Detector — TensorFlow 2 Object Detection API tutorial documentation还展示了一些适用于我们的例子的步骤。
此练习需要对上述文档(可能还有其他文档)进行一些研究,以获得转换后的文件。

额外的资源
使用来自TensorFlow文档的TFRecord和tf.train.Example(https://www.tensorflow.org/tutorials/load_data/tfrecord)
在接下来的练习时,可以参考上述文档。

11.练习3 -创建tf记录

目的
本练习的目的是熟悉tf记录格式。具体来说,是将Waymo Open Dataset中的数据转换为Tensorflow目标检测API使用的tf记录格式。作为一名机器学习工程师,需要将数据集从一种格式转换为另一种格式,这是一个很好的例子。

细节
这里(https://waymo.com/open/data/perception/关于Waymo Open Dataset数据格式的信息。每个tf记录文件包含了汽车整个行程的数据,这意味着它包含了来自不同摄像头的图像以及激光雷达数据。因为希望保持数据集较小,所以执行create_tf_example函数来创建清理过的tf记录文件。

说明-使用Waymo Open Dataset github存储库来解析原始tf记录文件。建议遵循本教程(GitHub - waymo-research/waymo-open-dataset: Waymo Open Dataset来更好地理解数据格式,然后再开始这个练习。

提示
文档(GitHub - Jossome/Waymo-open-dataset-document: The official document of the dataset is too general. There are many missing details. This document aims at making it more convenient to use the dataset.提供了数据集结构的概述。

稍后,利用Tensorflow目标检测API来训练目标检测模型。在API教程中,可以找到create_tf_example的示例(Training Custom Object Detector — TensorFlow 2 Object Detection API tutorial documentation

注意,运行该代码将需要使用/home/workspace目录中包含的example .tfrecord。

参考代码

import io
import osimport tensorflow.compat.v1 as tf
from PIL import Image
from waymo_open_dataset import dataset_pb2 as open_datasetfrom utils import parse_frame, int64_feature, int64_list_feature, bytes_feature \bytes_list_feature, float_list_featuredef create_tf_example(filename, encoded_jpeg, annotations):"""convert to tensorflow object detection API formatargs:- filename [str]: name of the image- encoded_jpeg [bytes-likes]: encoded image- annotations [list]: bboxes and classesreturns:- tf_example [tf.Example]"""encoded_jpg_io = io.BytesIO(encoded_jpeg)image = Image.open(encoded_jpg_io)width, height = image.sizemapping = {1: 'vehicle', 2: 'pedestrian', 4: 'cyclist'}image_format = b'jpg'xmins = []xmaxs = []ymins = []ymaxs = []classes_text = []classes = []filename = filename.encode('utf8')for ann in annotations:xmin, ymin = ann.box.center_x - 0.5 * ann.box.length, ann.box.center_y - 0.5 * ann.box.widthxmax, ymax = ann.box.center_x + 0.5 * ann.box.length,  ann.box.center_y + 0.5 * ann.box.widthxmins.append(xmin / width)xmaxs.append(xmax / width)ymins.append(ymin / height)ymaxs.append(ymax / height)    classes.append(ann.type)classes_text.append(mapping[ann.type].encode('utf8'))tf_example = tf.train.Example(features=tf.train.Features(feature={'image/height': int64_feature(height),'image/width': int64_feature(width),'image/filename': bytes_feature(filename),'image/source_id': bytes_feature(filename),'image/encoded': bytes_feature(encoded_jpeg),'image/format': bytes_feature(image_format),'image/object/bbox/xmin': float_list_feature(xmins),'image/object/bbox/xmax': float_list_feature(xmaxs),'image/object/bbox/ymin': float_list_feature(ymins),'image/object/bbox/ymax': float_list_feature(ymaxs),'image/object/class/text': bytes_list_feature(classes_text),'image/object/class/label': int64_list_feature(classes),}))return tf_exampledef process_tfr(path):"""process a waymo tf record into a tf api tf record"""# create processed data dirfile_name = os.path.basename(path)logger.info(f'Processing {path}')writer = tf.python_io.TFRecordWriter(f'{dest}/{file_name}')dataset = tf.data.TFRecordDataset(path, compression_type='')for idx, data in enumerate(dataset):frame = open_dataset.Frame()frame.ParseFromString(bytearray(data.numpy()))encoded_jpeg, annotations = parse_frame(frame)filename = file_name.replace('.tfrecord', f'_{idx}.tfrecord')tf_example = create_tf_example(filename, encoded_jpeg, annotations)writer.write(tf_example.SerializeToString())writer.close()if __name__ == "__main__": parser = argparse.ArgumentParser()parser.add_argument('-p', '--path', required=True, type=str,help='Waymo Open dataset tf record')args = parser.parse_args()  process_tfr(args.path)

其它资源

https://www.tensorflow.org/tutorials/load_data/tfrecord

12.Model Selection

ML工程师往往对创造新模型非常兴奋,然而,在深入到ML工作流的这一步之前,必须通过建立基线(baselines)来设定现实的期望

下基线可以了解最低的预期性能。如果得到的指标低于这样的基线,那么就发出一个危险的信号,应该担心培训管道(pipeline)出了问题。例如,对于一个分类问题,随机猜测基线是一个很好的下限。给定C类,你的算法的准确性应该高于1/C。

上基线可以了解期望的最大性能。如果客户要求提供一种100%正确分类图像的算法,可以放心地让他们知道这不会发生。人类的表现是一个很好的上限基线。对于分类问题,应该尝试手动分类100个图像,以了解算法可以达到什么样的性能水平。

模型选择是ML工作流的一个动态部分,它需要多次迭代。除非对该任务有一些先验知识,否则建议从简单的模型开始,并迭代复杂性。请记住,在此阶段验证集应该保持不变!

13.误差分析

验证集度量指标是模型全局性能的一个很好的指示器,但是我们经常需要更好的理解。例如,像精确度这样的指标不会告诉你某一类物体是否总是被错误分类。由于这些原因,必须在迭代模型之前进行深入的错误分析。

基于度量指标或损失值对预测进行排序,始终是识别错误模式的一种有用方法。

14.总结

机器学习的工作流程如下:

确定问题的框架:理解利害关系,并定义相关的指标。
理解数据:执行探索性数据分析,并从数据集中提取模式。
对模型进行迭代:创建验证集,建立基线,并对模型进行从简单到复杂的迭代。

15.术语

Accuracy(准确性):分类度量指标。
Bias-Variance tradeoff(偏差-方差权衡):如何创建一个性能良好的ML模型,同时保持对新数据的推广能力的挑战。
Cross validation(交叉验证):评估模型的一组技术
Domain gap(域差):数据集分布之间的差异。
Exploratory Data Analysis(探索性数据分析(EDA)):分析一个新的数据集并提取任何与ML问题相关的信息的过程。
Inference time(推断时间):模型输出预测所需的时间。
Overfitting(过拟合):当一个模型在数据集上有很好的性能,但不能很好地推广时
Precision(精度):正确分类实例的数量除以这些实例的数量。
Recall(召回率):正确分类的图片数量除以图片总数。
TfRecord: Tensorflow自定义数据格式。
Training set(训练集):用于训练ML模型的数据集。
Validation set(验证集):用于评估ML模型性能的数据集。

笔记:机器学习的工作流程相关推荐

  1. 微服务升级_SpringCloud Alibaba工作笔记0006---spring gateway工作流程

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 gateway的内容 gateway由三个部分组成, route路由:用来接收一个uri的 pre ...

  2. 方法 | 机器学习(深度学习)通用工作流程

    机器学习(深度学习)通用工作流程 Deep Learning with Python 4.5节 1. 定义问题并装载数据集(Defining the problem and assembling a ...

  3. Git笔记(21) 分布式工作流程

    Git笔记(21) 分布式工作流程 1. 分布式特性 2. 集中式工作流 3. 集成管理者工作流 4. 司令官与副官工作流 1. 分布式特性 同传统的集中式版本控制系统(CVCS)不同 Git 的分布 ...

  4. 机器学习(深度学习)通用工作流程

    机器学习(深度学习)通用工作流程 翻译 Deep Learning with Python 4.5节 1. 定义问题并装载数据集(Defining the problem and assembling ...

  5. 算法工程师面试备战笔记2_一个完整机器学习项目的流程

    1 抽象成数学问题 明确问题是进行机器学习的第一步.机器学习的训练过程通常都是一件非常耗时的事情,胡乱尝试时间成本是非常高的. 这里的抽象成数学问题,指的我们明确我们可以获得什么样的数据,目标是一个分 ...

  6. 使用Tand自动化您的机器学习工作流程

    This is a post on TanD, a no-code framework to automate the machine learning workflow. Its purpose i ...

  7. 【大数据入门笔记系列】第六节 分布式计算框架MapReduce的工作流程

    [大数据入门笔记系列]第六节 分布式计算框架MapReduce的工作流程 前言 MapReduce分布式运算 MapReduceApplication MapTask ReduceTask split ...

  8. Git 学习笔记:5 分布式工作流程

    Git 学习笔记:5 分布式工作流程 分布式工作流程 集中式工作流 集成管理员工作流 司令官与副官工作流 工作流程总结 向一个项目贡献 提交准则 私有小型团队 John's Machine 私有管理团 ...

  9. 人工智能概述、人工智能发展历程、人工智能主要分支、机器学习工作流程、完整机器学习项目的流程、机器学习算法分类、独立同分布、模型评估、深度学习简介

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 1.1 人工智能概述 1 人工智能应用场景 2 人工智能小案例 ...

最新文章

  1. 内存泄露的原因找到了,罪魁祸首居然是 Java TheadLocal
  2. mysql缓存淘汰机制_Redis缓存总结:淘汰机制、缓存雪崩、数据不一致....
  3. webdriver --API--(java版) the second part
  4. SQl 根据某列去重 partition by
  5. 什么是分布式锁?redis、zookeeper、etcd实现分布式锁有什么不同之处?
  6. js实现下拉框多选_bootstrap基础快速入门-10 dropdown下拉框
  7. 如何用函数初始化结构体
  8. SAP Spartacus Unit List Component的设计明细 - UnitListComponent
  9. 谈谈 css 的各种居中——读编写高质量代码有感
  10. Kinect开发笔记之一Kinect详细介绍
  11. bluR blUr bLur...闷的时候就听Blur
  12. urllib2的用法
  13. 自动化运维工具puppet(四)
  14. Python+OpenCV:图像轮廓
  15. Docker 基本操作
  16. matlab线性数据毛刺剔除,matlab滤波技术及区域处理---线性滤波
  17. 博通无线网卡驱动 linux,archlinux bcm4360 无线网卡驱动
  18. android沉浸式模式简书,Android-沉浸式模式
  19. iphone4 ios7电话号码格式修改
  20. Postman汉化教程

热门文章

  1. VBA:EXCEL粘贴时跳过有公式单元格
  2. CUDA C Dynamic Parallelism
  3. Openstack web界面登录异常处理
  4. 解决 Problematic frame: C [sigar-amd64-winnt.dll+0x14ed4] 问题 (JDK11 后版本生成 JRE, 得到当前进程)
  5. 专业素养计算机,我对计算机学科核心素养的理解
  6. “杭州最惨创业者”事件初步法律分析
  7. 【无线通信】无线通信系统结构演进(1)
  8. 技术出色的BitTorrent是如何倒掉的?
  9. 别找了,你要的资源都在这!!!安利一些福利(资源多多哟)
  10. 使用Python获取网段IP个数以及地址清单