MACHINELEARNING

    xcode9之后的打包方式

    XCode8.3之前的打包

    https://github.com/webfrogs/xcode_shell/blob/master/ipa-build
    阅读链接上的这个脚本, 可以理解构建三部曲为:

    1. Clean build cache
    2. 编译出.archive
    3. xcrun打包为.ipa文件

    第三步是和XCode9差异最大的地方, 先记住这里:

    XCode9之后的打包

    听说是8.3之后就不一样的了.
    细化上面的三个步骤为:

    Clean Build Cache:

    
    
    1
    
    
    
    xcodebuild clean -workspace $workspace -scheme $scheme -configuration $configuration
    

    与xcode8无任何差异.

    编译,生成.xcarchive

    xcodebuild archive -workspace $workspace -scheme $scheme -configuration 
        \ $configuration -archivePath $archivePath -destination generic/platform=ios 
        \ CODE_SIGN_IDENTITY="$code_sign_indentity"
    

    这里可以不需要这个参数, CODE_SIGN_IDENTITY="$code_sign_indentity".

    将.xcarchive生成.IPA

    xcodebuild -exportArchive -archivePath $archivePath 
        \ -exportPath $exportPath -destination generic/platform=ios 
        \ -exportOptionsPlist $exportOptionPlist -allowProvisioningUpdates
    

    这一步有特殊的地方, 就是-exportOptionsPlist $exportOptionPlist, 它的格式如下, 做了下扼要的说明, 官网能找到它的说明文档:

    Jun 5, 2018
    MachineLearning

    机器学习迁移模型到IOS

    https://paulswith.github.io/2018/02/24/%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0InceptionV3/ 上文记录了如何从一个别人训练好的模型, 切入我们自己的图片, 改为我们自己的模型.
    本来以为移植到手机很简单, 但是不简单的是我的模型本身就是迁移学习别人的模型,有很多莫名其面的坑, 在CoreML经历了N个坑后,1点14分我搞掂了.

    项目源码和转换源码已经上传到git.
    https://github.com/Paulswith/machineLearningIntro/tree/master/classification_101

    转化为mlmodel

    说说转换为mlmodel的工具有两个:

    接着往下看:

    是否是graph-pb?

    如果你跟我一样, 训练的模型, 从tensorflow的代码保存下来的, 调用的:

    saver.save(sess, MODEL_SAVEPATH, global_step=50)
    

    它并不会保存出一个pb文件, 其中的.meta也需要其他方式转换似乎也可以, 我没有尝试过.
    用这个方法, 你需要在上方代码的下面加两行,就可以继续:

    if i %SAVE_EPOCH == 0:
        tf.train.write_graph(sess.graph, MODEL_SAVE_DIR, 'model.pbtxt')
    

    pdtxt固化为pd

    操作参考链接 https://www.jianshu.com/p/091415b114e2
    我是直接使用的bezel, 编译tensorflow源码后, 直接使用, 其中参数跟着填, 需要注意的是output_node:

    导入化图

    导入图和查看图的节点信息:
    如果你的图不属于pb文件, 那么就会在导入图的时候报错的.

    with open(TF_MODEL_FILE, 'rb') as f:
        serialized = f.read()
    tf.reset_default_graph()
    original_gdef = tf.GraphDef()
    original_gdef.ParseFromString(serialized)
    ##2 可以在这里查看到全部的图信息(前提是你有转换成功)
    with tf.Graph().as_default() as g:
        tf.import_graph_def(original_gdef, name='')
        ops = g.get_operations()
        try:
            for i in range(10000):
                print('op id {} : op name: {}, op type: "{}"'.format(str(i),ops[i].name, ops[i].type))
        except:
            print("全部节点已打印完毕.")
            pass
    

    预处理节点

    其实这一步个人不是很清楚很知道它做了什么,但确是不得不做的. 最后的大小看着也不像是”减包”
    需要注意两点:

    Feb 25, 2018
    MachineLearning

    迁移学习InceptionV3

    手动画过AlexNet类似的模型,直接在后面加了一层[,class]的全连接层, 结果预测准确率是90%左右. 当然不是很满意. 于是乎开始各种方法寻求最准的CNN
    偶然间发现通过迁移学习大赛上高分的作品,进行迁移学习可以让我们拥有更精准的准确率,于是有了本文.
    总结:: 学会如何迁移优秀的模型来为自己所用!
    文章讲述的colab源码已经共享, 请点击下方链接查看即可.
    https://drive.google.com/file/d/1ahJtJvuHDGh4oS4lyNG0NdtqZuyns4J6/view?usp=sharing

    迁移准备

    模型选择准备

    首先当然是选择一款高效的模型,查阅了部分资料, 发现googleNet是2014年ILSVRC挑战赛获得冠军, 错误率降低到6.67%, 另一个名字也是InceptionV1, V3就是它优化后的第三代, 错误率更低
    模型下载:
    https://storage.googleapis.com/download.tensorflow.org/models/inception_dec_2015.zip 并解压得到.pd文件

    执行下方代码, 可以打印出pb文件的全部节点:

    tf_model_path = '/Users/akarizo/Desktop/inception_dec_2015/tensorflow_inception_graph.pb'
    with open(tf_model_path, 'rb') as f:
        serialized = f.read()
    tf.reset_default_graph()
    original_gdef = tf.GraphDef()
    original_gdef.ParseFromString(serialized)
    ##2 可以在这里查看到全部的图信息(前提是你有转换成功)
    with tf.Graph().as_default() as g:
        tf.import_graph_def(original_gdef, name='')
        ops = g.get_operations()
        try:
            for i in range(10000):
                print('op id {} : op name: {}, op type: "{}"'.format(str(i),ops[i].name, ops[i].type))
        except:
            pass
    

    需要关注的输入层:

    和需要被修改最后一层的全连接层:

    Feb 24, 2018
    MachineLearning

    部署TensorFlow到Colaboratory

    一个二分类的机器学习, 用TensorFlow写的, 刚好看到google提供的免费褥羊毛GPU, 虽然坑很多, 但还是部署上去了,GPU效率真的比CPU强的多多.
    官方完整的帮助连接 在这里,注意上面的代码是基于Python2的, 我用的python3

    数据集准备

    CSV之类的轻量数据集

    PASS, 有即可

    TFRecord重量数据集

    可以类似我这样子, 将数据存储到目录下Datasets下, 推荐tar压缩

    tar zcvf Datasets.gz Datasets

    自行配置好谷歌Drive, 链接 https://www.google.com/drive/
    下载符合电脑版本, 把数据集存入同步到云端.

    如何上传

    打开你的Colaboratory-new一个jupyter脚本.

    小文件上传

    from google.colab import files
    # 你需填的:
    FILE_NAME = '想保存到Colaboratory的文件名'
    uploaded = files.upload()
    with open(FILE_NAME, 'wb') as file:
        file.write(uploaded[list[uploaded.keys()][0]])
    

    对应的python执行上述代码后, 会出现Choose file按钮, 选择本地文件确认即可上传, 默认在当前路径, 可用!ls -l查看下

    大文件上传

    下面开始我就没有试过python2了,都是基于python3

    如果是大文件上传, 就按照前面的准备, 我们已经把文件传到了GoogleDrive云盘.
    Now, 在浏览器打开Drive找到那个文件, 右键->查看共享链接: -> 拷贝id=后面这个key, 粘贴到下方代码的位置

    # 这行代码相当于unix,会去帮我们安装这个包
    !pip install -U -q PyDrive
    from pydrive.auth import GoogleAuth
    from pydrive.drive import GoogleDrive
    from google.colab import auth
    from oauth2client.client import GoogleCredentials
    
    # 你需填的:
    PACKAGE_ID = 'key粘贴到这里'
    PACKAGE_NAME = 'drive文件的名字还是Colaboratory将存储的名字呢,你自己试试, 我就是填drive对应的名字'
    auth.authenticate_user()
    gauth = GoogleAuth()
    gauth.credentials = GoogleCredentials.get_application_default()
    drive = GoogleDrive(gauth)
    downloaded = drive.CreateFile({'id':PACKAGE_ID})
    downloaded.GetContentFile(PACKAGE_NAME)
    print('Transpose succeed.')
    

    执行上述代码, 会弹出一个授权链接和一个授权码输入框, 授权链接授权后会给你这串授权码,粘贴回车即可.依然可以用!ls -l查看下, Colaboratory有自带一些命令的, 在/bin下, 所以可以用tar命令进行解压:tar czvf Datasets.gz

    Feb 1, 2018
    MachineLearning

    TensorFlow数据集制作实战

    这是实战篇,往下看先

    当前数据


    当前我有这些图片数据, 分为是飞机(plane_)和不是飞机(plane_false)的二分类数据集原图.分别存在两个不同的文件夹

    • 数据1 -> 大概是1600+张
    • 数据0 -> 大概是160+张

    比例是10:1左右, 而数量1800+上来看也不是很理想, 我这里为了省事是直接水平翻转图片, 得到1800*2(待会见代码). 当然为了避免欠拟合情况当然更好的方法是挖掘更多的资源.

    根据文件夹标签化图片

    头部一些声明:

    import tensorflow as tf
    import os
    import random
    from PIL import Image
    plane_path = '/Users/dobby/Documents/data_img/plane'
    UNplane_path = '/Users/dobby/Documents/data_img/UNplane'
    records_path = '/Users/dobby/Documents/data_img/train.tfrecords'
    dataset_list = []
    

    遍历这两个文件夹, 如果是plane文件夹,那里面存储是label=1的图片, 反之是0. 进行标签化
    存储方式为(image_path, label)的元组 一起存储在dataset_list数组中

    def classic_data(path):
        # 根据目录标签数据
        if path == plane_path:
            label = 1
        else:
            label = 0
        file_list =  os.listdir(path)
        for each in file_list:
            if each[:5] != 'plane':
                continue
            im_full_path = os.path.join(path, each)
            dataset_list.append((im_full_path, label))
    

    转为数据集

    def create_record(data_list, should_transpose=False):
        """
         图片转为bytes写入
         字符串也是bytes
         1/0 Int
        """
        counter = 0
         # 新建一个写入session
        writer = tf.python_io.TFRecordWriter(records_path)
        for path,label in data_list:
            counter += 1
            print("{i},{j}n".format(i=path, j=label))
            # 打开图片
            img = Image.open(path)
            # 将图片统一大小
            img = img.resize((300, 300))
            # 转换为bytes
            img_raw = img.tobytes()
            data = tf.train.Example(
                features=tf.train.Features(
                    feature={
                        'label':tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), # 0/1 分类,所以是INT
                        'image':tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])) # 字符串/图片/语音用bytes
                    }
                )
            )
            writer.write(data.SerializeToString())
            if should_transpose:
                counter += 1
                # 将图片左右翻转后生成一张新的图片,label不变,
                rot_img = img.transpose(Image.FLIP_LEFT_RIGHT)
                rot_img_raw = rot_img.tobytes()
                data_2 = tf.train.Example(
                    features=tf.train.Features(
                        feature={
                            'label':tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),
                            'image':tf.train.Feature(bytes_list=tf.train.BytesList(value=[rot_img_raw]))
                        }
                    )
                )
                writer.write(data_2.SerializeToString())
        writer.close()
        print("写入数据集-DONE, 共存{}个数据".format(counter))
    
    • writer = tf.python_io.TFRecordWriter(records_path)启动一个写入TFRecord句柄, 遍历数组取出图片和label, 将图片设置统一大小并转为bytes.
    • tf.train.Example(tf.train.Features)是核心的处理代码, Example成TensorFlow的特定规则数据, 通过使用TFRecordWriter写入到TFRecord中.Example包含一个键值对数据结构(与dict相同), 使用属性features记录, 因此, 初始化时必须传入这个features参数
    • writer.write(data.SerializeToString())把Example序列成字符串写入TFRecord
    • should_transpose=False参数用来配置是否水平翻转图片, 并令数据扩大一倍
    • 当然关于TFRecord的写入具体规则, 如果需要可以参考该链接 Tensorflow: 文件读写

    测试是否写入成功

    执行函数代码, 需要注意, 我提前将数据存储在python的列表中的, 可以使用random.shuffle进行数据的洗牌

    Jan 20, 2018
    MachineLearning

    TensorFlow数据集-Dataset-API

    TensorFlow在学习的时候, 它是有一个mnist数据集让我们学习的. 通过batch_size来每轮数据训练的大小, 现在打算将一个我们实际的数据转换为跟mnist数据集一样的效果

    内存中自定义数据

    Dataset-API是1.3版引入的, 支持从内存中/硬盘中生成数据集.

    • 一维数组
      直接就是给到一维数组, 生成数据集
    dataset = tf.data.Dataset.from_tensor_slices(
        (np.array([1.0, 2.0, 3.0, 4.0, 5.0]), np.random.uniform(size=(5, 2)))
    )
    out_put="""
    元组的形式:
    (1.0, array([ 0.41459922,  0.75492457]))
    (2.0, array([ 0.47954237,  0.93916116]))
    (3.0, array([ 0.70576017,  0.58064858]))
    (4.0, array([ 0.8239234 ,  0.92814029]))
    (5.0, array([ 0.03073594,  0.16718188]))
    """
    
    • 字典
      字典的格式给到,结果也是字典, 按照key索引(这种用的比较多一些)
    dataset = tf.data.Dataset.from_tensor_slices(
        {
            "a": np.array([1.0, 2.0, 3.0, 4.0, 5.0]),
            "b": np.random.uniform(size=(5, 2))
        }
    )
    
    out_put="""
    字典的形式:
    {'a': 1.0, 'b': array([ 0.15337225,  0.97730736])}
    {'a': 2.0, 'b': array([ 0.89860896,  0.95473649])}
    {'a': 3.0, 'b': array([ 0.79198725,  0.84507321])}
    {'a': 4.0, 'b': array([ 0.27289686,  0.56223038])}
    {'a': 5.0, 'b': array([ 0.19825011,  0.44183586])}
    """
    

    两种输出验证方式

    当内存中数据生成后, 我们通过这两种方式来验证下
    dataset来自上方代码

    Jan 20, 2018
    MachineLearning