精华内容
下载资源
问答
  • 自己制作手写数字训练图片,全部都已经灰度化,二值化,归一化,处理好了,适合做迁移学习,也可直接训练模型
  • caffe应用-01灰度图像分类之手写数字识别 很多情况下,我们去做图像的分类可能和图像的颜色没有太大的关系,像手写体识别,人脸识别等。 mnist的这个例子是caffe官方自带的,他的数据源包括60000张的训练数据以及...

    caffe应用-01灰度图像分类之手写体数字识别

    • 很多情况下,我们去做图像的分类可能和图像的颜色没有太大的关系,像手写体识别,人脸识别等。
    • mnist的这个例子是caffe官方自带的,他的数据源包括60000张的训练数据以及10000张的测试数据。其中,每张都是大小为28*28像素的单通道(灰度值为0-255)图片。

    1.制作lmdb数据源

    • 将所需图片文件夹(tain和test)下载后放在一个文件夹里。此时,我们需要编写一个简单的python程序用来生成一个txt文件来描述这些图片的信息(包括其文件路径和label)
    • 这个python文件命名为createFileList.py,其内容如下:
    #ecoding:utf_8
    import os
    
    folderName = '/home/terrence/caffe_case/mnist/'
    
    
    for i in range(10):
        #列出文件夹所有文件
        dirList = os.listdir(folderName + 'train/' + str(i) + '/')
    
        f = open(folderName+'train.txt', 'a+');
        for name in dirList:
            print name
            f.write(str(i) + '/' + name + ' '+ str(i) +'\n')    
    f.close()
    
    for i in range(10):
        #列出文件夹所有文件
        dirList = os.listdir(folderName + 'test/' + str(i) + '/')
    
        f = open(folderName+'test.txt', 'a+');
        for name in dirList:
            print name
            f.write(str(i) + '/' + name + ' '+ str(i) +'\n')    
    f.close()
    
    • 运行这个程序,得到train.txt和test.txt。其格式如下图所示:
      这里写图片描述
    • 显而易见,其格式为 文件夹+文件名+label

    • 接下来,我们需要一个脚本来制作lmdb数据源了,这个脚本命名为create_lmdb.sh,内容如下:
    #!/usr/bin/env sh 
    # Create the imagenet lmdb inputs
    # N.B. set the path to the imagenet train + val data dirs
    # ~/caffe/examples/imagenet/create_imagenet.sh
    set -e
    
    EXAMPLE=/home/terrence/caffe_case/mnist 
    DATA=/home/terrence/caffe_case/mnist 
    TOOLS=/home/terrence/caffe/build/tools
    
    TRAIN_DATA_ROOT=/home/terrence/caffe_case/mnist/train/
    VAL_DATA_ROOT=/home/terrence/caffe_case/mnist/test/ 
    
    # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
    # already been resized using another tool.
    RESIZE=false
    if $RESIZE; then
      RESIZE_HEIGHT=28
      RESIZE_WIDTH=28
    else
      RESIZE_HEIGHT=0
      RESIZE_WIDTH=0
    fi
    
    if [ ! -d "$TRAIN_DATA_ROOT" ]; then
      echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
      echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
           "where the ImageNet training data is stored."
      exit 1
    fi
    
    if [ ! -d "$VAL_DATA_ROOT" ]; then
      echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
      echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
           "where the ImageNet validation data is stored."
      exit 1
    fi
    
    echo "Creating train lmdb..."
    
    GLOG_logtostderr=1 $TOOLS/convert_imageset \
        --resize_height=$RESIZE_HEIGHT \
        --resize_width=$RESIZE_WIDTH \
        --shuffle \
        --gray=true \
        $TRAIN_DATA_ROOT \
        $DATA/train.txt \
        $EXAMPLE/img_train_lmdb
    
    echo "Creating val lmdb..."
    
    GLOG_logtostderr=1 $TOOLS/convert_imageset \
        --resize_height=$RESIZE_HEIGHT \
        --resize_width=$RESIZE_WIDTH \
        --shuffle \
        --gray=true \
        $VAL_DATA_ROOT \
        $DATA/test.txt \
        $EXAMPLE/img_test_lmdb
    
    echo "Done."
    
    • 除了路径要修改之外,我们还需要加上–gray=true \一个参数,目的是代表将图像当做灰度图像来处理。此外,由于我们源数据的图像大小都是一样的(28*28),所以就不需要resize了,因此设置RESIZE=false。

    • 运行这个脚本,就可以生成这两个文件夹:img_test_lmdb和img_train_lmdb。至此,lmdb数据源制作完毕。

    2.训练数据

    • 训练数据的命令保存在train_lenet.sh这个脚本里了,内容如下:
    #!/usr/bin/env sh
    set -e
    
    /home/terrence/caffe/build/tools/caffe train --solver=/home/terrence/caffe_case/mnist/lenet_solver.prototxt $@
    # The train/test net protocol buffer definition
    net: "/home/terrence/caffe_case/mnist/lenet_train_test.prototxt" #lenet_train_test.prototxt
    # test_iter specifies how many forward passes the test should carry out.
    # In the case of MNIST, we have test batch size 100 and 100 test iterations,
    # covering the full 10,000 testing images.
    test_iter: 100
    # Carry out testing every 500 training iterations.
    test_interval: 500
    # The base learning rate, momentum and the weight decay of the network.
    base_lr: 0.01
    momentum: 0.9
    weight_decay: 0.0005
    # The learning rate policy
    lr_policy: "inv"
    gamma: 0.0001
    power: 0.75
    # Display every 100 iterations
    display: 100
    # The maximum number of iterations
    max_iter: 10000
    # snapshot intermediate results
    snapshot: 5000
    snapshot_prefix: "/home/terrence/caffe_case/mnist/model/lenet" #caffemodel
    # solver mode: CPU or GPU
    solver_mode: GPU
    
    name: "LeNet"
    layer {
      name: "mnist"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TRAIN
      }
      transform_param {
        scale: 0.00390625
      }
      data_param {
        source: "/home/terrence/caffe_case/mnist/img_train_lmdb"
        batch_size: 64
        backend: LMDB
      }
    }
    layer {
      name: "mnist"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TEST
      }
      transform_param {
        scale: 0.00390625
      }
      data_param {
        source: "/home/terrence/caffe_case/mnist/img_test_lmdb"
        batch_size: 100
        backend: LMDB
      }
    }
    layer {
      name: "conv1"
      type: "Convolution"
      bottom: "data"
      top: "conv1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 20
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "xavier"
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "pool1"
      type: "Pooling"
      bottom: "conv1"
      top: "pool1"
      pooling_param {
        pool: MAX
        kernel_size: 2
        stride: 2
      }
    }
    layer {
      name: "conv2"
      type: "Convolution"
      bottom: "pool1"
      top: "conv2"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      convolution_param {
        num_output: 50
        kernel_size: 5
        stride: 1
        weight_filler {
          type: "xavier"
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "pool2"
      type: "Pooling"
      bottom: "conv2"
      top: "pool2"
      pooling_param {
        pool: MAX
        kernel_size: 2
        stride: 2
      }
    }
    layer {
      name: "ip1"
      type: "InnerProduct"
      bottom: "pool2"
      top: "ip1"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      inner_product_param {
        num_output: 500
        weight_filler {
          type: "xavier"
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "relu1"
      type: "ReLU"
      bottom: "ip1"
      top: "ip1"
    }
    layer {
      name: "ip2"
      type: "InnerProduct"
      bottom: "ip1"
      top: "ip2"
      param {
        lr_mult: 1
      }
      param {
        lr_mult: 2
      }
      inner_product_param {
        num_output: 10
        weight_filler {
          type: "xavier"
        }
        bias_filler {
          type: "constant"
        }
      }
    }
    layer {
      name: "accuracy"
      type: "Accuracy"
      bottom: "ip2"
      bottom: "label"
      top: "accuracy"
      include {
        phase: TEST
      }
    }
    layer {
      name: "loss"
      type: "SoftmaxWithLoss"
      bottom: "ip2"
      bottom: "label"
      top: "loss"
    }
    
    • 这个文件需要制定文件路径的修改即可。

    • 这几个文件都创建完成后,我们就可以运行train_lenet.sh这个脚本了,运行完成会在model文件夹下生成迭代5000以及10000次的最终模型结构的描述文件,其中的以.caffemodel结尾的文件在我们测试的时候会用到。

    2-1 训练数据的减均值操作

    • 讲到这里我们以及训练完了数据,可是还没有做减均值的操作,在这个应用里因为没有做也可以达到一个很好的效果,所以就不打算做了。
    • 接下来,会讲到如何做减均值这一步的操作。

    • 首先,我们要创建一个mean.sh的脚本:
    sudo /home/terrence/caffe/build/tools/compute_image_mean ./img_train_lmdb ./mean.binaryproto
    • 它就是将img_train_lmdb这个训练的lmdb数据源减均值并存放在mean.binaryproto文件下。运行脚本就可以得到此文件了。

    • 使用这个文件也很简单,我们需要在lenet_train_test.prototxt文件中的数据层指定这个文件的位置:
      这里写图片描述

    3. 利用训练好的模型测试图片

    • 测试某一张图片需要以下指令:

      python classify.py --print_results --force_grayscale --center_only --labels_file ./synset_words.txt ./02972.png resultsfile
      
    • 其中,02972.png是一张手写体数字图片:

    这里写图片描述

    • 然后是synset_words.txt文件,描述网络输出的10个数字代表的含义:
    0 zero
    1 one
    2 two
    3 three
    4 four
    5 five
    6 six
    7 seven 
    8 eight
    9 nine
    

    最后是一个classify.py文件,它指定了一些测试相关的信息:

    #!/usr/bin/env python  
    #coding:utf-8  
    """  
    classify.py is an out-of-the-box image classifer callable from the command line.  
    
    By default it configures and runs the Caffe reference ImageNet model.  
    """  
    caffe_root = '/home/terrence/caffe/'    
    import sys    
    sys.path.insert(0, caffe_root + 'python')    
    
    import numpy as np  
    import os  
    import sys  
    import argparse  
    import glob  
    import time  
    import pandas as pd #插入数据分析包  
    
    import caffe  
    
    
    def main(argv):  
        pycaffe_dir = os.path.dirname(__file__)  
    
    parser = argparse.ArgumentParser()  
    # Required arguments: input and output files.  
    parser.add_argument(  
        "input_file",  
        help="Input image, directory, or npy."  
    )  
    parser.add_argument(  
        "output_file",  
        help="Output npy filename."  
    )  
    # Optional arguments.  
    parser.add_argument(  
        "--model_def",  
        default=os.path.join(pycaffe_dir,  
                "./deploy.prototxt"), #指定deploy.prototxt的模型位置  
        help="Model definition file."  
    )  
    parser.add_argument(  
        "--pretrained_model",  
        default=os.path.join(pycaffe_dir,  
                "./model/lenet_iter_10000.caffemodel"), #指定caffemodel模型位置,这就是我们前面自己训练得到的模型  
        help="Trained model weights file."  
    )  
    #######新增^^^^^^^^^start^^^^^^^^^^^^^^^^^^^^^^  
    parser.add_argument(  
        "--labels_file",  
        default=os.path.join(pycaffe_dir,  
                "./synset_words.txt"), #指定输出结果对应的类别名文件???????????????????????????  
        help="mnist result words file"  
    )  
    parser.add_argument(  
        "--force_grayscale",  
        action='store_true',   #增加一个变量将输入图像强制转化为灰度图,因为lenet-5训练用的就是灰度图  
        help="Converts RGB images down to single-channel grayscale versions," +  
                   "useful for single-channel networks like MNIST."  
    )  
    parser.add_argument(  
        "--print_results",  
        action='store_true', #输入参数要求打印输出结果  
        help="Write output text to stdout rather than serializing to a file."  
    )  
    #######新增^^^^^^^^^end^^^^^^^^^^^^^^^^^^^^^^  
    parser.add_argument(  
        "--gpu",  
        action='store_true',  
        help="Switch for gpu computation."  
    )  
    parser.add_argument(  
        "--center_only",  
        action='store_true',  
        help="Switch for prediction from center crop alone instead of " +  
             "averaging predictions across crops (default)."  
    )  
    parser.add_argument(  
        "--images_dim",  
        default='28,28', #指定图像寬高  
        help="Canonical 'height,width' dimensions of input images."  
    )  
    parser.add_argument(  
        "--mean_file",  
        default=os.path.join(pycaffe_dir,  
                             './meanfile.npy'), #指定均值文件  
        help="Data set image mean of [Channels x Height x Width] dimensions " +  
             "(numpy array). Set to '' for no mean subtraction."  
    )  
    parser.add_argument(  
        "--input_scale",  
        type=float,  
        help="Multiply input features by this scale to finish preprocessing."  
    )  
    parser.add_argument(  
        "--raw_scale",  
        type=float,  
        default=255.0,  
        help="Multiply raw input by this scale before preprocessing."  
    )  
    parser.add_argument(  
        "--channel_swap",  
        default='2,1,0',  
        help="Order to permute input channels. The default converts " +  
             "RGB -> BGR since BGR is the Caffe default by way of OpenCV."  
    )  
    parser.add_argument(  
        "--ext",  
        default='jpg',  
        help="Image file extension to take as input when a directory " +  
             "is given as the input file."  
    )  
    args = parser.parse_args()  
    
    image_dims = [int(s) for s in args.images_dim.split(',')]  
    
    mean, channel_swap = None, None  
    if args.mean_file:  
        mean = np.load(args.mean_file).mean(1).mean(1)  
    if args.channel_swap:  
        channel_swap = [int(s) for s in args.channel_swap.split(',')]  
    
    if args.gpu:  
        caffe.set_mode_gpu()  
        print("GPU mode")  
    else:  
        caffe.set_mode_cpu()  
        print("CPU mode")  
    
    # Make classifier.  
    classifier = caffe.Classifier(args.model_def, args.pretrained_model,  
            image_dims=image_dims, mean=mean,  
            input_scale=args.input_scale, raw_scale=args.raw_scale,  
            channel_swap=None)  
    
    # Load numpy array (.npy), directory glob (*.jpg), or image file.  
    args.input_file = os.path.expanduser(args.input_file)  
    if args.input_file.endswith('npy'):  
        print("Loading file: %s" % args.input_file)  
        inputs = np.load(args.input_file)  
    elif os.path.isdir(args.input_file):  
        print("Loading folder: %s" % args.input_file)  
        inputs =[caffe.io.load_image(im_f)  
                 for im_f in glob.glob(args.input_file + '/*.' + args.ext)]  
    else:  
        print("Loading file: %s" % args.input_file)  
        inputs = [caffe.io.load_image(args.input_file,not args.force_grayscale)] #强制图片为灰度图  
    
    print("Classifying %d inputs." % len(inputs))  
    
    # Classify.  
    start = time.time()  
    scores = classifier.predict(inputs, not args.center_only).flatten()  
    print("Done in %.2f s." % (time.time() - start))  
    
    #增加输出结果打印到终端^^^start^^^^^  
    # print  
    if args.print_results:  
        with open(args.labels_file) as f:  
            labels_df = pd.DataFrame([{'synset_id':l.strip().split(' ')[0], 'name': ' '.join(l.strip().split(' ')[1:]).split(',')[0]} for l in f.readlines()])  
            labels = labels_df.sort('synset_id')['name'].values  
    
            indices =(-scores).argsort()[:5]  
            predictions = labels[indices]  
            print predictions  
            print scores  
    
            meta = [(p, '%.5f' % scores[i]) for i,p in zip(indices, predictions)]  
            print meta  
    #增加输出结果打印到终端vvvvendvvvvvvv  
    
    
    # Save  
    print("Saving results into %s" % args.output_file)  
    np.save(args.output_file, predictions)  
    
    
    if __name__ == '__main__':  
        main(sys.argv)    
    
    • 这里需要注意的就是指定一个mean_file文件,这是均值文件,因为我们在lenet_train_test.prototxt并没有做减均值的操作,所以生成一个值为0大小是(28*28*1)的数组即可,注意是[Channels x Height x Width]

    • 生成数组的python代码如下:

      import numpy as np
      zeros = np.zeros((1,28,28), dtype=np.float32)
      np.save('meanfile.npy', zeros) 
      

    4. 测试结果

    这里写图片描述

    展开全文
  • 数字图像设计制作基础一个好的作品的产生认为包括三个方面。从基础开始说是计算机表达,构图能力和创意。但作品的产生过程是相反的:首先有了好的创意,然后把它在脑海中进行粗略构图,借助简单的计算机手段,或者...

    数字图像设计制作基础

    一个好的作品的产生认为包括三个方面。从基础开始说是计算机表达,构图能力和创意。但作品的产生过程是相反的:首先有了好的创意,然后把它在脑海中进行粗略构图,借助简单的计算机手段,或者手绘,变成较为详细的草图。最后综合运用计算机技巧出成果图。所以说三者缺一不可,但有时又各有侧重。有些非常经典的创意,寥寥几笔就可以表现,不需要什么技巧,但是这种情况是非常少的。我们平时所大量制作和接触的,都是精美、优秀的作品,而不是经典的作品。所以其他两个方面是必须掌握的。 ????关于构图就是指三大构成的综合应用,即平面构成,色彩构成和立体构成。对于平面设计者来说,前两个犹为重要。构图在一般作品中起到的作用是最重要的。通过合理的组织各种元素,安排视觉中心,使图面美观并引导读者的目光和兴趣,为你的创意服务。简言之就是把你自己的创意想法,组织为脑海中可实现的并可识别的一张图。计算机表达就不用多说了,就是把刚才存在于你脑海中的图落实到计算机中,使别人也能看到。计算机在这里纯粹起一个工具的作用,但你的水平至少要高到心里想得到什么效果,就可以表现出来。比如一个复杂的螺旋,一个金属效果,等等。同时也要具有一定的绘图速度,不要让一双笨手影响了想法的落实。正所谓心到手到。 ????创意总是不稳定的东西,它需要思维的跳跃,灵活而善变;有关构图,只要人们的审美不变,它是永远都不会变的。计算机水平则是有规律的,不断变化着的。这里说明构图能力是最重要的。三方面的修养要相辅相成,不能逐个进行。初学者有时会想先把软件学好了,再学构图。其实基本命令掌握了以后就可以进行构图的尝试了。然后作品也就越来越有深度了。 ????下面谈一下怎么加强这三方面的修养。 ????计算机表达,无须多言,一条途径是从教程开始。网上有大量的免费资源,不乏好的教程。除去基础教程,特效教程可以使你知道一条命令的其他用处和组合命令的魅力。如ps中组合滤镜就可以创造出几乎无所不能的效果。看教程的时候不要一步一步跟着做,先不开软件通看几遍,在脑海中操作一次,然后不看教程默做一遍。如果哪步忘了,也不要去看这一步,再通看一遍,默做。总之保证整个过程是一气呵成的。这样有助于对命令的整体认识。否则的话,可以说做了白做,很快就忘记了。教程的唯一目的,不是让你学会了他做的什么,而是他的命令是怎么用的。学完一个,立即可以举一反三,效果最好。你可以在学完后不久就忘了那个教程是做了什么东西,但你必须记着那几条命令是怎么用的,并且还可以再怎么用。 ????另一条途径是自己提出问题,自己解决。这种方法可能耗费的时间多一些,作为第一条途径的辅助。但是可以有深刻的印象,增加自信心。说白了就是自己写教程。撇开设计,它也能培养独立解决未知问题的能力。 ????总之是学习阶段(这个阶段是永恒的)要不断有作品产生。不要嫌弃它们的拙劣,它们是通往成功道路的基石。 ????关于构图当然也是以练为主。平面构成比较简单,可以在没事的时候或者无聊的时候找张白纸随便画(即所谓“涂鸦”),同时也可以练习造型能力。比如枯燥的选修课上,听音乐的时候,或者开会的时候。在心如止水的状态下很多灵感就随着笔头流出来了。虽然计算机表达日趋完善,手头功夫始终是根本。平构的书有很多。一些作品里面也能清楚的领会到。在计算机上练习小图,先用黑白位图(只有黑白两种颜色)。就是纸上的美工笔,钢笔所表达的效果;差不多了就开始用灰度的做。也就是铅笔素描,水彩单色渲染的效果;灰度的用熟了就可以练彩色的了,也就是色彩构成。立体构成培养空间思维,平面作品只是体现在二维介质上,但很多是表现三维空间的。 ????刚才谈到的其实就是美术基础修养的问题。非美术出身的朋友其实只要练好了三大构成就可以了。它们虽然是逐级难度增加的,但我们在日常生活中是经常自发的不经意的用到的。比如你在摄影时相机里的取景框,平日出门衣服的颜色、款式搭配,室内家具的摆设,乃至你向垃圾堆里扔一包新垃圾时的随意一丢都无不分别或综合应用了这些构图原理。自觉的加强这方面的修养,它们都是严格遵循了审美原则的。你的生活空间将和你的作品一样,自然而迷人。 ????最后是创意的问题。乍看起来它好象是偶然的,不可琢磨的。其实只要付出了劳动,灵感会不停向你招手的。 ????首先,灵感的出现源于生活。 ????丰富的生活经历是提供灵感的源泉。要积极的体验生活,努力尝试各种新的事物。如果你没有去过西餐厅,没有听过音乐会,没有看过现场球赛或是没有在草原上策马飞奔,那么你赶紧去。你可以进迪厅而不跳舞,干小工而不要钱,……总之是为了能够感受不同的环境,不同的心境。所有的阅历,无论好的坏的,都是人生的资本,最大的财富。 ????当设计任务迫在眉头时逛街是一个短时间取得创意的不错的主意。从熙熙攘攘的人

    展开全文
  • TensorFlow下利用MNIST训练模型并识别自己手写数字 test2.m:利用matlab将图片转为28*28像素 test3.m:完成灰度化与二值化处理 运行完前两个文件,图片的预处理就算成功了 也可以使用opencv.py:利用opencv对图片就...
  • 实施一对多的Logistic回归和神经网络来识别手写数字 多类分类和神经网络 在这个项目中,我实现了对所有逻辑回归和神经网络来识别手写数字。 要开始使用该项目,您将需要下载代码并将其内容解压缩到希望运行该项目的...
  • 这些数据集是从28×28像素大小的手写数字灰度图像中得来,其中训练数据第一个元素是具体的手写数字,剩下的784个元素是手写数字灰度图像每个像素的灰度值,范围为[0,255],测试数据则没有训练数据中的第一个元素,只...

    昨天我在Kaggle上下载了一份用于手写数字识别的数据集,想通过最近学习到的一些方法来训练一个模型进行手写数字识别。这些数据集是从28×28像素大小的手写数字灰度图像中得来,其中训练数据第一个元素是具体的手写数字,剩下的784个元素是手写数字灰度图像每个像素的灰度值,范围为[0,255],测试数据则没有训练数据中的第一个元素,只包含784个灰度值。现在我打算使用Spark MLlib中提供的朴素贝叶斯算法来训练模型。

    首先来设定Spark上下文的一些参数:

    val conf = new SparkConf()
        .setAppName("DigitRecgonizer")
        .setMaster("local[*]")
        .set("spark.driver.memory", "10G")
    val sc = new SparkContext(conf)

    这样Spark上下文已经创建完毕了,那么现在来读取训练数据吧,在这里我把原本的训练数据的header去掉了,只保留了数据部,训练数据是以csv格式保存的:

    val rawData = sc.textFile("file://path/train-noheader.csv")

    由于数据是csv格式,所以接下来用“,”将每行数据转换成数组:

    val records = rawData.map(line => line.split(","))

    下面需要将这些数据处理成朴素贝叶斯能够接受的数据类型LabeledPoint ,此类型接收两个参数,第一个参数是label(标签,在这里就是具体的手写数字),第二个参数是features (特征向量,在这里是784个灰度值):

        val records = rawData.map(line => line.split(","))
        val data = records.map{ r =>
          val label = r(0).toInt
          val features = r.slice(1, r.size).map(p => p.toDouble)
          LabeledPoint(label, Vectors.dense(features))
        }

    现在已经把数据都准备好了,可以开始训练模型了,在MLlib中,只需要简单地调用train 方法就能完成模型的训练:

    val nbModel = NaiveBayes.train(data)

    现在已经训练出了一个模型,我们看看它在训练数据集上的准确率如何,在这里我将训练数据集的特征传给模型进行训练,将得到的结果与真实的结果进行对比,然后统计出正确的条数,以此来评估模型的准确率,这应该也算是一种交叉验证吧:

        val nbTotalCorrect = data.map { point =>
          if (nbModel.predict(point.features) == point.label) 1 else 0
        }.sum
        val numData = data.count()
        val nbAccuracy = nbTotalCorrect / numData

    运行完这段代码,我得到的准确率是0.8261190476190476

    下面开始对测试数据进行识别了,首先读入测试数据:

    val unlabeledData = sc.textFile("file://path/test-noheader.csv")

    再用与之前同样的方式进行预处理:

    val unlabeledRecords = unlabeledData.map(line => line.split(","))
    val features = unlabeledRecords.map{ r =>
      val f = r.map(p => p.toDouble)
      Vectors.dense(f)
    }

    注意,测试数据中没有标签,所以将它所有数值都作为特征features

    现在开始对测试数据进行识别,并把结果保存为文件:

        val predictions = nbModel.predict(features).map(p => p.toInt)
        predictions.repartition(1).saveAsTextFile("file://path/digitRec.txt")

    到这里所有工作都完成了,之后我把计算出来的结果上传到Kaggle上,发现准确率在0.83左右,与我之前在训练数据集上得到的评估结果相近。

    今天就到这里吧,以后可能还会寻找其他的方式来训练模型,看看效果如何。

    展开全文
  • 进行手写数字的图片预测的时候碰到了这样的问题。 先说说处理图片有三种方式 一、matplotlib 二、PIL 三、opencv 一、matplotlib 1、显示图片 import matplotlib.pyplot as plt #plt 用于显示图片 import matplotlib...

    python 读取、保存、二值化、灰度化图片+opencv处理图片的方法

    进行手写数字的图片预测的时候碰到了这样的问题。

    先说说处理图片有三种方式
    一、matplotlib
    二、PIL
    三、opencv

    一、matplotlib

    1、显示图片
    import matplotlib.pyplot as plt #plt 用于显示图片
    import matplotlib.image as mpimg #mpimg 用于读取图片
    import numpy as np
    lena = mpimg.imread('lena.png') #读取和代码处于同一目录下的lena.png
    

    此时 lena 就已经是一个 np.array 了,可以对它进行任意处理

    lena.shape #(512, 512, 3)
    plt.imshow(lena) # 显示图片
    plt.axis('off') # 不显示坐标轴
    plt.show()
    
    2、显示图片的第一个通道
    lena_1 = lena[:,:,0]
    plt.imshow('lena_1')
    plt.show()
    

    此时会发现显示的是热量图,不是我们预想的灰度图,可以添加 cmap 参数,有如下几种添加方法:

    方法一
    plt.imshow('lena_1', cmap='Greys_r')
    plt.show()
    
    方法二
    img = plt.imshow('lena_1')
    img.set_cmap('gray') # 'hot' 是热量图
    plt.show()
    
    3、将 RGB 转为灰度图
    def rgb2gray(rgb):
        return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
    
    gray = rgb2gray(lena)    
    

    也可以用 plt.imshow(gray, cmap = plt.get_cmap(‘gray’))

    plt.imshow(gray, cmap='Greys_r')
    plt.axis('off')
    plt.show()
    
    4、对图像进行放缩
    from scipy import misc
    lena_new_sz = misc.imresize(lena, 0.5) # 第二个参数如果是整数,则为百分比,如果是tuple,则为输出图像的尺寸
    plt.imshow(lena_new_sz)
    plt.axis('off')
    plt.show()
    

    附上imresize的用法
    功能:改变图像的大小。
    用法:

    B = imresize(A,m)
    B = imresize(A,m,method)
    B = imresize(A,[mrows ncols],method)
    B = imresize(...,method,n)
    B = imresize(...,method,h)
    

    imrersize函数使用由参数method指定的插值运算来改变图像的大小。
    method的几种可选值:

    'nearest'(默认值)最近邻插值
    'bilinear'双线性插值
    'bicubic'双三次插值
    B = imresize(A,m)表示把图像A放大m倍
    B = imresize(...,method,h)中的h可以是任意一个FIR滤波器(h通常由函数ftrans2、fwind1、fwind2、或fsamp2等生成的二维FIR滤波器)。
    
    5、保存 matplotlib 画出的图像
    plt.savefig('lena_new_sz.png')
    

    将 array 保存为图像

    from scipy import misc
    misc.imsave('lena_new_sz.png', lena_new_sz)
    

    直接保存 array

    #读取之后还是可以按照前面显示数组的方法对图像进行显示,这种方法完全不会对图像质量造成损失
    np.save('lena_new_sz', lena_new_sz) # 会在保存的名字后面自动加上.npy
    img = np.load('lena_new_sz.npy') # 读取前面保存的数组
    

    二、PIL

    1、显示图片
    from PIL import Image
    im = Image.open('lena.png')
    im.show()
    
    2、将 PIL Image 图片转换为 numpy 数组
    im_array = np.array(im)
    

    也可以用 np.asarray(im) 区别是 np.array() 是深拷贝,np.asarray() 是浅拷贝

    3、保存 PIL 图片

    直接调用 Image 类的 save 方法

    from PIL import Image
    I = Image.open('lena.png')
    I.save('new_lena.png')
    
    4、将 numpy 数组转换为 PIL 图片
    这里采用 matplotlib.image 读入图片数组,注意这里读入的数组是 float32 型的,范围是 0-1,而 PIL.Image 数据是 uinit8 型的,范围是0-255,所以要进行转换:
    
    import matplotlib.image as mpimg
    from PIL import Image
    lena = mpimg.imread('lena.png') # 这里读入的数据是 float32 型的,范围是0-1
    im = Image.fromarray(np.uinit8(lena*255))
    im.show()
    
    5、RGB 转换为灰度图、二值化图
    from PIL import Image
    I = Image.open('lena.png')
    I.show()
    L = I.convert('L')   #转化为灰度图
    L = I.convert('1')   #转化为二值化图
    L.show()
    

    附:PIL可以对图像的颜色进行转换,并支持诸如24位彩色、8位灰度图和二值图等模式,简单的转换可以通过Image.convert(mode)函数完
    成,其中mode表示输出的颜色模式,例如’‘L’‘表示灰度,’‘1’'表示二值图模式等。但是利用convert函数将灰度图转换为二值图时,是采用
    固定的阈 值127来实现的,即灰度高于127的像素值为1,而灰度低于127的像素值为0。

    三、opencv

    首先需要安装opencv,接下来演示在windows平台下python安装opencv,即实现import cv2功能。

    在官网:http://opencv.org/上找到OpenCV
    windows版下载下来。然后安装opencv,配置环境变量。

    这里是python安装opencv的步骤:
    (1)在opencv的安装目录”
    \opencv\build\python\2.7\x64”或”\opencv\build\python\2.7\x86”(根据python版本)文件夹中找到cv2.pyd;
    (2)复制到Python安装目录的”\Python27\Lib\site-packages”文件夹中。
    然后在python的环境下测试import cv2 是否成功导入就好了。

    附上寻找python安装路径的方法:
    在python的环境下键入
    python -c “import os; print os.file”
    就可以看到根目录的位置

    接下来开始描述如何利用opencv简单地处理图像

    1、读取图像,并把图像转换为灰度图像并显示
    import cv2
    im = imread("./image.jpg")  #读取图片
    im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)   #转换了灰度化
    cv2.axis("off")
    cv2.title("Input Image")
    cv2.imshow(im_gray, cmap="gray")  #显示图片
    cv2.show()
    
    2、固定阈值二值化

    retval, im_at_fixed = cv2.threshold(im_gray, 50, 255,
    cv2.THRESH_BINARY)
    #将阈值设置为50,阈值类型为cv2.THRESH_BINARY,则灰度在大于50的像素其值将设置为255,其它像素设置为0

    cv2.axis("off") 
    cv2.title("Fixed Thresholding")
    cv2.imshow(im_at_fixed, cmap = 'gray') 
    cv2.show()
    

    附:固定阈值二值化处理利用cv2.threshold函数,此函数的原型为:
    cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst
    其中:
    1、src 为输入图像;
    2、thresh 为阈值;
    3、maxval 为输出图像的最大值;
    4、type 为阈值的类型;
    5、dst 为目标图像。

    附cv2.threshold函数的常用参数
    1、cv2.THRESH_BINARY(黑白二值)
    2、cv2.THRESH_BINARY_INV(黑白二值反转)
    3、cv2.THRESH_TRUNC (得到的图像为多像素值)
    4、cv2.THRESH_TOZERO
    5、cv2.THRESH_TOZERO_INV

    3、算术平法的自适应二值化
    im_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 10)
    #上面我们将b设置为5,常数设置为10。
    cv2.axis("off")
    cv2.title("Adaptive Thresholding with mean weighted average")
    cv2.imshow(im_at_mean, cmap = 'gray') 
    cv2.show()
    

    #附:算术平均法的自适应二值化利用cv2.adaptiveThreshold实现,此函数的原型为:
    cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
    其中:
    1、src 为输入图像;
    2、maxval 为输出图像的最大值;
    3、adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
    4、thresholdType: 阈值的类型;
    5、blockSize: b的值;
    6、C 为从均值中减去的常数,用于得到阈值;
    7、dst 为目标图像。

    4、高斯加权均值法自适应二值化
    im_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 7)
    cv2.axis("off")
    cv2.title("Adaptive Thresholding with gaussian weighted average")
    cv2.imshow(im_at_mean, cmap = 'gray') 
    cv2.show()
    

    #附:高斯加权均值法自适应二值化也是利用cv2.adaptiveThreshold, 此函数的原型与上述相同:
    cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
    其中:
    1、src 为输入图像;
    2、maxval 为输出图像的最大值;
    3、adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
    4、thresholdType: 阈值的类型;
    5、blockSize: b的值;
    6、C 为从均值中减去的常数,用于得到阈值;
    7、dst 为目标图像。

    5、保存图片
    直接用cv2.imwrite
    import cv2
    cv2.imwrite("./new_img.jpg", img)
    cv2.imwrite("./new_img.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 5])
    

    第一个参数是保存的路径及文件名,第二个是图像矩阵。
    第三个参数针对特定的格式:
    对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。
    对于PNG,第三个参数表示的是压缩级别。cv2.IMWRITE_PNG_COMPRESSION,从0到9,压缩级别越高,图像尺寸越小。默认级别为3
    注意cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。

    6、创建于复制图片

    如果要创建图像,需要使用numpy的函数
    创建空的图片

    emptyImage = np.zeros(img.shape, np.uint8)
    

    复制原有的图片

    emptyImage2 = img.copy(); 
    

    用cvtColor获得原图像的副本

    emptyImage3=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
    emptyImage3[...]=0  
    后面的emptyImage3[...]=0是将其转成空白的黑色图像。
    
    展开全文
  • python_手写数字识别案例、手写数字图片处理 #1、手写数字识别案例 步骤: 收集数据 带有标签的训练数据集来源于trainingDigits文件夹里面所有的文件,接近2000个文件,每个文件中有32*32的二维数组,由01构成...
  • Python(TensorFlow框架)实现手写数字识别系统

    万次阅读 多人点赞 2019-07-31 11:27:55
    本文使用Tensorflow框架进行Python编程实现基于卷积神经网络的手写数字识别算法,并将其封装在一个GUI界面中,最终,设计并实现了一个手写数字识别系统。
  • MNIST手写数字数据集

    2017-04-09 14:26:14
    MNIST是在机器学习领域中的一个经典问题。该问题解决的是把28x28像素的灰度手写数字图片识别为相应的数字,其中数字的范围从0到9. MNIST包含了训练集与测试集数据。
  • MNIST手写数字数据库

    2019-03-04 15:32:50
    MNIST手写数字图像数据库 60000个训练集,10000个测试集,灰度图,大小均为为28*28 train-images-idx3-ubyte.gz: training set images (9912422 bytes) train-labels-idx1-ubyte.gz: training set labels (28881 ...
  • MATLAB手写数字识别

    万次阅读 多人点赞 2019-07-31 14:07:22
    本文主要是根据《matlab手写神经网络实现识别手写数字》博客中的代码进行试验。由于没有数据集,所以采用了MNIST数据集进行代码的运行。数据集不同所以需要对代码进行微小改动。 简介 数据处理:4000张作为训练样本...
  • 写在前面其实我之前写过一个简单的识别手写数字的程序,但是因为逻辑比较简单,而且要求比较严苛,是在50x50大小像素的白底图上手写黑色数字,并且给的训练材料也不够多,导致准确率只能五五开。所以这一次准备写一...
  • 美国邮政服务USPS手写数字识别库,库中为16×16像素的灰度图像,共有9298个手写数字图像。对于要做迁移学习(Transfer Learning)、连续学习(Life Long learning)等的研究来说,是除mnist之外又一实用的数据集。
  • 现在网上流行的mnist数据集共有两个版本1、tensorflow 提供的 点击此处下载2、开源标准数据集 点击此处下载连续向下的几篇文章将是一套系列文章,都是对mnist的开源标准数据集进行手写数字识别的在我之前的所有文章...
  • 现在要用自己的手写数字进行识别 使用自己的手写数字进行识别 主要部分如下 def application(): testNum = int(input("input the number of test pictures:")) for i in range(testNum): testPic = i...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,945
精华内容 3,178
关键字:

如何制作灰度手写数字