美文网首页我爱编程
深度学习零基础学习笔记一(优达学城)

深度学习零基础学习笔记一(优达学城)

作者: linanwx | 来源:发表于2017-07-19 14:42 被阅读0次

    前言

    突发奇想想学机器学习,这里是学习过程的笔记

    准备

    我做了这些准备工作

    • MacBook 一台,搭建好Python环境,安装numpy和matplotlib
    • 优达学城注册免费的《深度学习》课程(Google合作)
    • 廖雪峰Python入门教程学习
    • 花费两天时间大致浏览《机器学习实战》

    学习这些知识应该足以进行接下来的优达学城的学习

    课程一 从机器学习到深度学习

    前言

    小节1-8,主要介绍了深度学习的发展现状等等知识。

    image.png

    小节9-12介绍了softmax模型。

    粗略浏览机器学习实战后,在机器学习实战这本书中,大致介绍了机器学习的几种算法。从表面上来看,机器学习是一些分类和聚类算法。在这些算法中,介绍了一种算法,叫做逻辑回归分类。

    在小节9-12中,主要介绍了分类器模型——逻辑回归,分类函数使用的是softmax函数。

    • 什么是softmax函数
    softmax

    这张图片可以表明什么是softmax函数了。对原来数列中的每个数z求exp(z),新数的大小所占的比例就是新数的softmax概率。

    • 性质

    如果输入同比例扩大,则分类器的结果越两极化,越自信,如果输入同比例缩小,分类器结果趋于平均,不自信。

    • 算法
    import numpy as np
    def softmax(x):
        """Compute softmax values for each sets of scores in x."""
        expList = [np.exp(i) for i in x]
        expSum = sum(expList)
        x = [i/expSum for i in expList]
        return np.array(x)
    
    image.png

    13-14节主要讲One-Hot编码。在softmax函数给出一组概率数列之后,如何确定分类呢?例如概率最高的为1,其他的为0,这样的一个数列,属于One-Hot编码。这种编码是已经确定了分类。

    交叉熵

    15-16节讲了交叉熵。softmax可以计算概率数列,OneHot是已经确定的分类,那如何计算概率数列到某个分类的距离呢?使用交叉熵来度量这个距离。

    image.png image.png

    17-20 节讲解了如何使用这个分类器。其中,18节讲了为什么需要采用一种特殊的初始数据。

    sum = 1000000000
    
    for i in range(1000000):
        sum += 0.000001
    
    sum -= 1000000000
    print(sum)
    

    这段代码运行结果不是1。如果把sum换成一个很小的数字,例如1,而不是1000000000,我们发现结果误差变小了。基于这个原因,我们希望初始数据总是均值为0,并且各个方向的方差为一致的。例如一个灰度图片的像素值0-255,我们需要把它减去128,然后除以128,这样每一个数字都是-1到1之间的数字,这样的初始数据更适合用来训练。

    image.png

    这样,我们就可以进行训练了。回顾一下视频内容,xi是训练数据矩阵,w是随机权重矩阵,为了性能,随机值取自正态分布中轴为0,方差很小的分布函数,然后计算概率数列,和目标的距离。然后求出到所有目标的平均距离。我们的目的是让距离变小,所以我们沿着梯度下降的方向优化权重矩阵,同时优化截距b。不断重复这一个过程,直到局部最优为止。

    • 安装docker

    https://www.docker-cn.com/community-edition#/download

    配置官方中国镜像。

    image.png
    • 安装jupyter notebook

    $ pip3 install jupyter
    $ jupyter notebook
    此时可以使用命令jupyter notebook打开一个jupyter编辑器

    • tensorflow环境搭建

    $ docker run -it -p 8888:8888 tensorflow/tensorflow
    运行上述命令会自动下载tensorflow镜像,前提是仓库镜像设置成中国的镜像,否则下载很慢。运行命令后,会提示你打开网页,打开这个网址以后会显示tensorflow的jupyter编辑环境,前提是jupyter notebook安装正确

    • 挂载docker的文件目录
      我们需要把官方的作业导进去。关闭容器,重新打开容器,使用-v 主机目录:容器目录来进行挂载。
      docker run -v /Users/hahaha/tensorflow/:/notebooks -it -p 8888:8888 tensorflow/tensorflow

    其中/Users/hahaha/tensorflow/是我的mac的一个文件夹,notebooks是tensorflow中的jupyter默认编辑目录。

    在主机目录的挂载目录下面粘贴第一个作业文件,1_notmnist.ipynb。这个文件可以在这里找到: 1_notmnist.ipynb

    作业一内容

    作业代码段一

    首先运行一下第一段代码的import,应该是没有任何出错的,此时什么也不会发生,如果出现了红色的输出错误,那就说明这些from import没有导入成功。

    # These are all the modules we'll be using later. Make sure you can import them
    # before proceeding further.
    from __future__ import print_function
    # print函数
    import matplotlib.pyplot as plt
    # 绘图工具
    import numpy as np
    # 矩阵计算
    import os
    # 文件路径
    import sys
    # 文件输出
    import tarfile
    # 解压缩
    from IPython.display import display, Image
    # 显示图片
    from scipy import ndimage
    # 图像处理
    from sklearn.linear_model import LogisticRegression
    # 逻辑回归模块线性模型
    from six.moves.urllib.request import urlretrieve
    # url处理
    from six.moves import cPickle as pickle
    # 数据处理
    
    # Config the matplotlib backend as plotting inline in IPython
    %matplotlib inline
    # matplotlib是最著名的Python图表绘制扩展库,
    # 它支持输出多种格式的图形图像,并且可以使用多种GUI界面库交互式地显示图表。
    # 使用%matplotlib命令可以将matplotlib的图表直接嵌入到Notebook之中,
    # 或者使用指定的界面库显示图表,它有一个参数指定matplotlib图表的显示方式。
    # inline表示将图表嵌入到Notebook中。
    

    作业代码段二

    接下来是第二段代码,会进行下载用于训练和测试的字母集合,大概是300mb大小。下载成功后,可以看到挂载目录下面的这两个文件。

    作业
    url = 'https://commondatastorage.googleapis.com/books1000/'
    last_percent_reported = None
    data_root = '.' # Change me to store data elsewhere
    
    def download_progress_hook(count, blockSize, totalSize):
      """A hook to report the progress of a download. This is mostly intended for users with
      slow internet connections. Reports every 5% change in download progress.
      """
    # 钩子函数用来实时显示下载进度
      global last_percent_reported
      percent = int(count * blockSize * 100 / totalSize)
    
      if last_percent_reported != percent:
        if percent % 5 == 0:
          sys.stdout.write("%s%%" % percent)
          sys.stdout.flush()
        else:
          sys.stdout.write(".")
          sys.stdout.flush()
          
        last_percent_reported = percent
            
    def maybe_download(filename, expected_bytes, force=False):
      """Download a file if not present, and make sure it's the right size."""
      dest_filename = os.path.join(data_root, filename)
    #   data_root是当前目录,在这个目录上加上文件名,设置为要保存的文件位置
      if force or not os.path.exists(dest_filename):
    #         force是强制下载,忽略已经下载的文件
        print('Attempting to download:', filename) 
        filename, _ = urlretrieve(url + filename, dest_filename, reporthook=download_progress_hook)
    #     使用urlretrieve来下载文件,挂上钩子
        print('\nDownload Complete!')
      statinfo = os.stat(dest_filename)
    # 获取下载到的文件的信息
      if statinfo.st_size == expected_bytes:
    #         正确大小
        print('Found and verified', dest_filename)
      else:
    #     错误大小,提示用户使用浏览器下载
        raise Exception(
          'Failed to verify ' + dest_filename + '. Can you get to it with a browser?')
      return dest_filename
    
    train_filename = maybe_download('notMNIST_large.tar.gz', 247336696)
    test_filename = maybe_download('notMNIST_small.tar.gz', 8458043)
    

    作业代码段三

    解压缩用例

    num_classes = 10
    # 数字总共有多少个
    np.random.seed(133)
    # 初始化随机种子
    def maybe_extract(filename, force=False):
    #     假设已经解压缩了
      root = os.path.splitext(os.path.splitext(filename)[0])[0]  # remove .tar.gz
    #     splitext(filename)[0]用于去除一个后缀,用两次就是去除两次后缀,也就是去除.tar.gz这个后缀
      if os.path.isdir(root) and not force:
        # You may override by setting force=True.
    #     已经解压缩了就不再解压缩了
        print('%s already present - Skipping extraction of %s.' % (root, filename))
      else:
        print('Extracting data for %s. This may take a while. Please wait.' % root)
        tar = tarfile.open(filename)
        sys.stdout.flush()
        tar.extractall(data_root)
        tar.close()
    #     解压缩到当前目录下面
      data_folders = [
        os.path.join(root, d) for d in sorted(os.listdir(root))
        if os.path.isdir(os.path.join(root, d))]
      if len(data_folders) != num_classes:
        raise Exception(
          'Expected %d folders, one per class. Found %d instead.' % (
            num_classes, len(data_folders)))
      print(data_folders)
    # 检查解压缩文件目录的数量与期待是否一致,并且打印解压缩出来文件的目录
      return data_folders
      
    train_folders = maybe_extract(train_filename)
    test_folders = maybe_extract(test_filename)
    

    问题一

    写出代码显示解压缩的文件内容信息

    • 参考答案
    import random
    import matplotlib.image as mpimg
    
    
    def plot_samples(data_folders, sample_size, title=None):
        fig = plt.figure()
    #     建立空图像
        if title: fig.suptitle(title, fontsize=16, fontweight='bold')
    #         加入标题
        for folder in data_folders:
    #         遍历每个字母
            image_files = os.listdir(folder)
            image_sample = random.sample(image_files, sample_size)
    #         从该字母中随机选取一定数量的图片
            for image in image_sample:
                image_file = os.path.join(folder, image)
                ax = fig.add_subplot(len(data_folders), sample_size, sample_size * data_folders.index(folder) +
                                     image_sample.index(image) + 1)
    #             创建一个子图
                image = mpimg.imread(image_file)
    #     加载子图图片
                ax.imshow(image)
    #     显示子图图片
                ax.set_axis_off() 
    #     关闭子图坐标线
    
        fig.set_size_inches(18.5, 10.5)
    #     设置图片显示的大小
        plt.show()
    
    
    plot_samples(train_folders, 20, 'Train')
    plot_samples(test_folders, 20, 'Test')
    

    运行效果如下

    训练.png 测试.png

    可以看出,部分训练数据是有问题的

    作业代码段四

    这之后需要进行数据的归一化处理,就是让图像的每一个像素由0255变换到-1.01.0,并且持久化到文件中

    image_size = 28  # Pixel width and height.
    pixel_depth = 255.0  # Number of levels per pixel.
    # 图片长宽和图片像素深度
    def load_letter(folder, min_num_images):
      """Load the data for a single letter label."""
    # 处理一个属于一个字母文件夹下面的文件
      image_files = os.listdir(folder)
    #     列出该文件夹目录下面的所有文件
      dataset = np.ndarray(shape=(len(image_files), image_size, image_size),
                             dtype=np.float32)
    #     创建一个长度为文件个数,宽度和高度为28的
        
      print(folder)
    # 打印目录
      num_images = 0
    # 初始化num_images
      for image in image_files:
    #   对每一个文件处理
        image_file = os.path.join(folder, image)
    #     获取完整文件路径
        try:
          image_data = (ndimage.imread(image_file).astype(float) - 
                        pixel_depth / 2) / pixel_depth
    #     读入图像,并且归一化处理
          if image_data.shape != (image_size, image_size):
    #         检查图像的宽高
            raise Exception('Unexpected image shape: %s' % str(image_data.shape))
          dataset[num_images, :, :] = image_data
    #         读入到数据集合中
          num_images = num_images + 1
    #     图片序号加一
        except IOError as e:
    #         如果无法读取文件的话,则忽略该文件
          print('Could not read:', image_file, ':', e, '- it\'s ok, skipping.')
        
      dataset = dataset[0:num_images, :, :]
    # 如果读进来的文件数量少于最小需要文件数量
      if num_images < min_num_images:
        raise Exception('Many fewer images than expected: %d < %d' %
                        (num_images, min_num_images))
    #     显示缺少的文件数量
      print('Full dataset tensor:', dataset.shape)
    #     显示文件数量,图片长宽
      print('Mean:', np.mean(dataset))
    #     平均值
      print('Standard deviation:', np.std(dataset))
    #     标准差
      return dataset
            
    def maybe_pickle(data_folders, min_num_images_per_class, force=False):
      dataset_names = []
      for folder in data_folders:
    #         对每一个字母文件夹处理
        set_filename = folder + '.pickle'
    #     设置输出的文件
        dataset_names.append(set_filename)
    #     设置处理过的文件夹
        if os.path.exists(set_filename) and not force:
          # You may override by setting force=True.
    #     检查是否存在已处理过的文件
          print('%s already present - Skipping pickling.' % set_filename)
        else:
          print('Pickling %s.' % set_filename)
          dataset = load_letter(folder, min_num_images_per_class)
    #         归一化处理这个文件夹下面的所有图片
          try:
            with open(set_filename, 'wb') as f:
              pickle.dump(dataset, f, pickle.HIGHEST_PROTOCOL)
    #         持久化数据,将数据保存在硬盘上,而不是一直放在内存中
          except Exception as e:
            print('Unable to save data to', set_filename, ':', e)
      
      return dataset_names
    
    train_datasets = maybe_pickle(train_folders, 45000)
    test_datasets = maybe_pickle(test_folders, 1800)
    

    问题2

    显示处理过的图片

    • 参考答案
    def plot_samples_2(data_folders, sample_size, title=None):
        fig = plt.figure()
    #     建立空图像
        if title: fig.suptitle(title, fontsize=16, fontweight='bold')
    #         加入标题
        for folder in data_folders:
    #         遍历每个字母
            with open(folder, 'rb') as pk_f:
                data = pickle.load(pk_f)
                for index, image in enumerate(data):
                    if index < sample_size :
    #         从该字母中随机选取一定数量的图片
                        ax = fig.add_subplot(len(data_folders), sample_size, sample_size * data_folders.index(folder) +
                                     index + 1)
    #     加载子图图片
                        ax.imshow(image)
    #     显示子图图片
                        ax.set_axis_off() 
    #     关闭子图坐标线
    
        fig.set_size_inches(18.5, 10.5)
    #     设置图片显示的大小
        plt.show()
        
    
    plot_samples_2(train_datasets, 20, 'Train')
    plot_samples_2(test_datasets, 20, 'Test')
    
    image.png image.png

    问题3

    检查每个字母下面的文件数目是否相似。

    • 参考答案
    file_path = 'notMNIST_large/{0}.pickle'
    for ele in 'ABCDEFJHIJ':
        with open(file_path.format(ele), 'rb') as pk_f:
    #         遍历每一个目录
            dat = pickle.load(pk_f)
    #     加载这个目录下面的持久化文件
        print('number of pictures in {}.pickle = '.format(ele), dat.shape[0])
    #     打印相关信息
    

    结果表明数目基本一致。


    问题3效果

    代码段——数据分割

    数据不可能一次性就全部加载到内存中,这里对这些数据进行分割,接下来的这份代码对数据进行了分割

    def make_arrays(nb_rows, img_size):
      if nb_rows:
        dataset = np.ndarray((nb_rows, img_size, img_size), dtype=np.float32)
    #     创建一个空集合,数据类型是长rows宽img_size高img_size的矩阵,数据类型是浮点32位
        labels = np.ndarray(nb_rows, dtype=np.int32)
    #     创建一个标签,数据类型是32位整型,长度是rows
      else:
        dataset, labels = None, None
      return dataset, labels
    # 返回创建的数据类型
    
    def merge_datasets(pickle_files, train_size, valid_size=0):
      num_classes = len(pickle_files)
    #     需要处理的类别数量
      valid_dataset, valid_labels = make_arrays(valid_size, image_size)
    #     建立有效数据集合,长度为有效长度
      train_dataset, train_labels = make_arrays(train_size, image_size)
    #     建立训练数据集合,长度为训练长度
      vsize_per_class = valid_size // num_classes
      tsize_per_class = train_size // num_classes
    # 计算给定训练长度和有效长度下每个类别的平均长度
    
      start_v, start_t = 0, 0
    # 初始化下标,start_v是有效数据的开始,start_t是训练数据的开始
      end_v, end_t = vsize_per_class, tsize_per_class
    # 初始化下标,end_v是有效数据的结束,end_t是训练数据的结束
      end_l = vsize_per_class + tsize_per_class
    # 初始化下标,end_l是字母集合的结束,等于每个类别有效数据的长度+训练数据的长度
      for label, pickle_file in enumerate(pickle_files):  
    #         遍历每一个pickle_file
        try:
          with open(pickle_file, 'rb') as f:
    #         打开这个持久化文件
            letter_set = pickle.load(f)
    #       加载数据集
            # let's shuffle the letters to have random validation and training set
            np.random.shuffle(letter_set)
    #       打乱数据集的顺序
            if valid_dataset is not None:
    #         如果不是测试集的话,更新测试集,否则 valid_dataset 不更新
              valid_letter = letter_set[:vsize_per_class, :, :]
    #         numpy切片     http://brieflyx.me/2015/python-module/numpy-array-split/
    #         从打乱的数据中选择 每类有效数据 数量的数据进行处理,放到 valid_letter 中
              valid_dataset[start_v:end_v, :, :] = valid_letter
    #         把这份数据放到valid_dataset中
              valid_labels[start_v:end_v] = label
    #         标记label 应该是 0~9中的一种
              start_v += vsize_per_class
              end_v += vsize_per_class
    #         更新下标
    #       循环结束时, valid_dataset 应该总长度为 valid_size 的一份数据, valid_labels是对应位置的标签
    
            train_letter = letter_set[vsize_per_class:end_l, :, :]
    #       除去valid部分的随机其他元素,长度为 end_l - vsize_per_class = tsize_per_class
            train_dataset[start_t:end_t, :, :] = train_letter
    #       循环结束时,train_dataset应该是总长为 train_size 的 一份数据
            
    #       
            train_labels[start_t:end_t] = label
            start_t += tsize_per_class
            end_t += tsize_per_class
    #       更新下标
        except Exception as e:
          print('Unable to process data from', pickle_file, ':', e)
          raise
        
      return valid_dataset, valid_labels, train_dataset, train_labels
                
                
    train_size = 200000
    valid_size = 10000
    test_size = 10000
    
    valid_dataset, valid_labels, train_dataset, train_labels = merge_datasets(
      train_datasets, train_size, valid_size)
    _, _, test_dataset, test_labels = merge_datasets(test_datasets, test_size)
    
    print('Training:', train_dataset.shape, train_labels.shape)
    print('Validation:', valid_dataset.shape, valid_labels.shape)
    print('Testing:', test_dataset.shape, test_labels.shape)
    

    代码段——打散数据

    permutation函数介绍:http://www.jianshu.com/p/f0eb10acaa2d

    def randomize(dataset, labels):
    #     labels.shape[0] 是 labels 的长度
      permutation = np.random.permutation(labels.shape[0])
    #     随机取出这么多数字的打乱
      print(labels.shape[0])
      shuffled_dataset = dataset[permutation,:,:]
    # 打乱数据
      shuffled_labels = labels[permutation]
    # 打乱标签
      return shuffled_dataset, shuffled_labels
    train_dataset, train_labels = randomize(train_dataset, train_labels)
    test_dataset, test_labels = randomize(test_dataset, test_labels)
    valid_dataset, valid_labels = randomize(valid_dataset, valid_labels)
    

    问题4

    检验打散后的数据是否正确

    • 参考答案
    import random
    def plot_sample_3(dataset, labels, title):
        fig = plt.figure()
        plt.suptitle(title, fontsize=16, fontweight='bold')
    #     设置标题样式
        items = random.sample(range(len(labels)), 200)
    #     打散 labels 长的顺序序列
        for i, item in enumerate(items):
    #         随机取一个
            plt.subplot(10, 20, i + 1)
    #     画子图
            plt.axis('off')
    #     关闭坐标轴
            plt.title(chr(ord('A') + labels[item]))
    #     加标题
            plt.imshow(dataset[item])
    #     显示对应位置的子图
        fig.set_size_inches(18.5, 10.5)
        plt.show()
    #     显示图片
     
    plot_sample_3(train_dataset, train_labels, 'train dataset suffled')
    plot_sample_3(valid_dataset, valid_labels, 'valid dataset suffled')
    plot_sample_3(test_dataset, test_labels, 'test dataset suffled')
    
    问题4

    省略类似的两图

    代码段——保存数据

    pickle_file = os.path.join(data_root, 'notMNIST.pickle')
    # 输出文件路径
    try:
      f = open(pickle_file, 'wb')
    # 打开这个文件
      save = {
        'train_dataset': train_dataset,
        'train_labels': train_labels,
        'valid_dataset': valid_dataset,
        'valid_labels': valid_labels,
        'test_dataset': test_dataset,
        'test_labels': test_labels,
        }
    #     写入一个字典 string-ndarray
      pickle.dump(save, f, pickle.HIGHEST_PROTOCOL)
      f.close()
    except Exception as e:
      print('Unable to save data to', pickle_file, ':', e)
      raise
    

    代码段——显示保存数据的大小

    statinfo = os.stat(pickle_file)
    print('Compressed pickle size:', statinfo.st_size)
    

    问题5

    题目的Google翻译

    通过构建,此数据集可能包含大量重叠样本,包括验证和测试集中也包含的训练数据! 训练和测试之间的重叠可能会使结果偏斜,如果您希望在没有重叠的环境中使用您的模型,但如果您希望在使用训练样本时再次看到训练样本,那么实际上是可以的。 测量培训,验证和测试样本之间的重叠程度。
    可选问题:
    数据集之间的重复数据怎么样? (几乎相同的图像)
    创建一个消毒验证和测试集,并比较您在随后的作业中的准确性。

    大概意思是训练数据不能和测试用的数据重合,否则导致准确度不准

    参考代码:

    • 仅仅查看重复的图片数量
    import hashlib
    
    pickle_file = os.path.join('.', 'notMNIST.pickle')
    try:
        with open(pickle_file, 'rb') as f:
            data = pickle.load(f)
    except Exception as e:
      print('Unable to open data from', pickle_file, ':', e)
      raise
    # 自从保存数据后,如果kernel挂了,就可以从本地直接读取,不用重新运行之前的代码
    # 如果报错的话,可以在网上搜索报错的异常
    
    def calcOverlap(sourceSet, targetSet, description):
        sourceSetMd5 = np.array([hashlib.md5(img).hexdigest() for img in sourceSet])
    #     建立一个md5表格
        targetSetMd5 = np.array([hashlib.md5(img).hexdigest() for img in targetSet])
    #     建立一个md5表格
        overlap = np.intersect1d(sourceSetMd5, targetSetMd5, assume_unique=False)
    #     去重
        print(description)
        print("overlap",overlap.shape[0], "from",sourceSetMd5.shape[0],"to", targetSetMd5.shape[0])
        print("rate",overlap.shape[0]*100.0/sourceSetMd5.shape[0],"% and", overlap.shape[0]*100.0/targetSetMd5.shape[0],"%")
    #     打印重叠数量
    
    
    calcOverlap(data['train_dataset'], data['valid_dataset'], "train_dataset & valid_dataset")
    calcOverlap(data['train_dataset'], data['test_dataset'], "train_dataset & test_dataset")
    calcOverlap(data['test_dataset'], data['valid_dataset'], "test_dataset & valid_dataset")```
    
    ![运行效果](https://img.haomeiwen.com/i4388248/2882159fe68dc672.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    - 去除重复图片资源
    待更新
    
    ## 问题6
    使用逻辑回归训练模型并且进行测试
    
    - 参考代码
    
    

    import random
    def disp_sample_dataset(dataset, labels,trueLabels, title=None):

    展示训练的结果

    fig = plt.figure()
    if title: fig.suptitle(title, fontsize=16, fontweight='bold')
    

    设置标题样式

    items = random.sample(range(len(labels)), 200)
    

    随机选择一系列图片

    for i, item in enumerate(items):
        plt.subplot(10, 20, i + 1)
    

    设置一个子图

        plt.axis('off')
    

    关闭坐标线

        lab = str(chr(ord('A') + labels[item]))
        trueLab = str(chr(ord('A') + trueLabels[item]))
        if lab == trueLab:
            plt.title( lab )
        else:
            plt.title(lab + " but " + trueLab)
    

    加上标题

        plt.imshow(dataset[item])
    

    显示这个图片

    fig.set_size_inches(18.5, 10.5)
    plt.show()
    

    def train_and_predict(train_dataset, train_labels, test_dataset, test_labels ,sample_size):
    regr = LogisticRegression()

    生成训练器

    X_train = train_dataset[:sample_size].reshape(sample_size, 784)
    

    根据sample_size选择要训练的数据量

    把二维向量压缩到一维向量

    y_train = train_labels[:sample_size]
    

    取出训练数据

    regr.fit(X_train, y_train)
    

    训练数据

    X_test = test_dataset.reshape(test_dataset.shape[0], 28 * 28)
    

    将测试数据压缩到一维向量

    y_test = test_labels
    

    测试数据所对应的真实标签

    pred_labels = regr.predict(X_test)
    

    生成预测数据

    print('Accuracy:', regr.score(X_test, y_test), 'when sample_size=', sample_size)
    disp_sample_dataset(test_dataset, pred_labels, test_labels, 'sample_size=' + str(sample_size))
    

    train_and_predict(data['train_dataset'],data['train_labels'],data['test_dataset'],data['test_labels'], 1000)

    
    ![image.png](https://img.haomeiwen.com/i4388248/6b3fb8a1d1b1ce34.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    ## 模型性能
    
    小节22~27提到了模型性能的相关知识。我们通常希望模型的性能能够达到100%,显然是不可能的。并且,为了使训练集的准确性提高,模型可能会发生过拟合。这时要遵循两点。
    - 不要将训练数据一次性使用,而是分块使用,每次训练一部分
    - 当模型参数使30个以上的用例由错误变成正确,则这个参数的改变是有效果的。
    
    
    ![模型性能](https://img.haomeiwen.com/i4388248/033910ba1d5c09e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ## 随机梯度下降
    小节29~31讲解了什么是随机梯度下降
    在训练过程中,为了让模型朝着最优的方向走,需要计算该点的导数。1.导数的计算量比较大,我们需要随机选择一部分样本来计算导数,来代替真实的导数。这就是随机梯度下降。2.为了减缓随机选择的随机性,我们使用动量的惯性来减少随机性。3.为了让后期模型能够稳定,我们减少学习的步长。
    
    课程一结束
    
    
    > 作业代码参考
    > http://www.hankcs.com/ml/notmnist.html

    相关文章

      网友评论

        本文标题:深度学习零基础学习笔记一(优达学城)

        本文链接:https://www.haomeiwen.com/subject/jsuohxtx.html