读书笔记-失控

全书概览

凯文·凯利在《失控》中探讨了生命、机器与社会系统的共同进化规律。他提出"失控"并非贬义,而是指一种去中心化的、自组织的、涌现式的控制方式。这种控制方式正在成为我们理解复杂系统的新范式——从生态系统到经济网络,从人工智能到社会演化,都遵循着相似的法则。

这本书让我重新思考了"控制"的含义。传统的控制是自上而下、集中式的;而自然界和进化选择了另一种路径——去中心化、分布式的涌现控制。这种"失控"实际上是一种更高级的控制形式,它让系统具备了适应性、韧性和创造力。


章节笔记

1. 共同进化与系统思维

本章要点

  • 共同进化是物种间交互的进化演变
  • 均衡态意味着死亡,系统需要非均衡才能保持活力
  • 网状因果循环取代了线性因果关系

我的感悟

本章的核心观点是"均衡即死亡"。这个观点深刻揭示了自然界和复杂系统的本质。我们习惯于追求稳定和均衡,但真正的生命力恰恰来自非均衡状态。生态系统、经济系统、社会组织都是如此——变化太多会导致混乱,但完全均衡则意味着停滞和死亡。

这让我想到现代企业管理的困境。很多公司追求"优化"和"效率",试图消除所有波动和变数。但这种追求恰恰可能扼杀组织的创新能力。健康的系统需要在秩序和混沌之间保持动态平衡。

个人笔记

生态学家偏爱自然界中的各种均衡状态,其主要原因和经济学家偏爱经济中的各种均衡状态相同:均衡态可以用数学模型来表达

经济学和生态学都迷恋均衡态,因为均衡态便于建模和预测。但真实世界是复杂的、非均衡的。这提醒我们在做决策时,不要过度依赖简化的模型。

原文摘录

共同进化是互相影响的物种间交互的进化演变。

均衡态不仅意味着死亡,它本身就是死亡状态。系统要变得丰富,就需要时间和空间上的变化。


2. 第四个间断

本章要点

  • 哥白尼、达尔文、弗洛伊德分别消除了三个认知间断
  • 第四个间断是人类与机器之间的间断
  • 生命可能从碳结构转化到硅结构

我的感悟

这个框架非常精彩。哥白尼打破了地球中心论,达尔文打破了人类中心论,弗洛伊德打破了理性中心论。现在我们面临的第四个间断,是打破生物中心论——承认机器也可以具有"生命"的属性。

凯利提出的"机械飞升"概念令人深思。如果生命可以从碳基转移到硅基,那么我们对"生命"的定义就需要重新审视。这不是科幻,而是正在发生的现实。人工智能、神经网络、进化算法,都是这个趋势的早期迹象。

个人笔记

这就是近年来知识体系的成长历程

每一次知识革命都是在消除一个"我们很特殊"的幻觉。我们不是宇宙中心,不是生物进化的终点,甚至可能不是智慧的唯一载体。

原文摘录

生命是否也能从碳结构中提取出来,转化成硅结构

我们一直渴望成为神灵。如果借助我们的努力,超生命能找到某种合适的途径,进化出使我们愉悦或对我们有益的生物,那我们会感到骄傲。


3. 加密与控制

本章要点

  • 加密技术是互联网发展的必要反作用力
  • 隐私正在成为一种定价销售的商品
  • 加密技术加剧了"失控"状态

我的感悟

本章关于加密技术的讨论极具前瞻性。凯利指出,加密不是为了对抗连接,而是为了给"无限连接"提供必要的断开能力。没有断开的能力,系统就会冻结成一团"超载的乱麻"。

这个洞见在今天的社交网络时代尤其重要。我们被连接得太多、太紧密,以至于失去了思考的空间。加密技术不仅是技术问题,更是关于"选择性断开"的哲学问题。

个人笔记

花钱买隐私

这是一个深刻的讽刺。在一个信息唾手可得的世界里,“不被人找到"反而成了奢侈品。隐私从基本权利变成了付费服务。

将难以计费的物品,切割到足够的粒度单位,购买这些所需的单位而付费

这是数字经济的基本逻辑——把原本难以计费的内容或服务,切分成可度量、可交易的小单位。

原文摘录

加密胜出,因为它是必要的反作用力,防止互联网不加节制地联结。任由互联网自行发展,它就会把所有人、所有东西都联结在一起。

加密技术允许蜂巢文化所渴求的必要的失控,以在向不断深化的缠结演变中保持灵活和敏捷。


4. 进化与选择

本章要点

  • 遗传算法的核心是"累积选择"而非随机选择
  • 进化能够制造出比工程学更复杂的东西
  • “爬山法"容易陷入局部最优

我的感悟

凯利清晰地解释了进化为什么比随机搜索更有效——关键在于"累积选择”。每一步选择都被保留下来,成为下一步的基础。这与纯粹的随机尝试有本质区别。

“爬山法"的困境也很有启发性。进化算法容易找到局部最优解,但可能错过全局最优。这提醒我们,在解决问题时,有时需要"跳出"当前的搜索空间,重新审视问题本身。

个人笔记

机器学习,梯度下降,局部最优陷阱

现代深度学习也面临同样的问题。虽然梯度下降能找到局部最优,但真正的突破往往来自"跳出"这个优化过程——比如改变网络架构、引入新的训练范式。

引入可控失控,并行处理评估结果,继续

进化的力量在于它同时尝试成千上万种可能性。这种"并行试错"是工程学无法比拟的。

原文摘录

我们知道,只有两种方法能制造出结构极其复杂的东西:一个是依靠工程学,另一个是通过进化。而在两者中,进化能够制造出更加复杂的东西。

如何培养出能在恶劣条件下生存的生物体?通过同时投入一千个略有差异的个体。


5. 控制的未来

本章要点

Feb 26, 2026
books

ClaudeCode用上高性价比的国产大模型

如何在国内使用极具性价比的国产大模型替代claude code自家的模型。

首次绕过初始化

  1. 首次终端claude提示要登录,修改~/.claude.json绕过初始化
{
  "hasCompletedOnboarding": true
}

使用国产模型

  1. 修改~/.claude/settings.json,添加"env",加入下列环境变量对
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://dashscope.aliyuncs.com/apps/anthropic",
    "ANTHROPIC_API_KEY": "sk-xxxxxxxxxxxx",
    "ANTHROPIC_MODEL": "glm-5"
  }
}
  1. (可选)智能选择模型,依照json语法加到步骤2,claude会根据任务情况选择模型
ANTHROPIC_DEFAULT_OPUS_MODEL="glm-5" # 用于复杂推理、架构设计等高难度任务。
ANTHROPIC_DEFAULT_SONNET_MODEL="MiniMax-M2.5" # 用于代码编写、功能实现等日常任务
ANTHROPIC_DEFAULT_HAIKU_MODEL="qwen3.5-plus" # 用于语法检查、文件搜索等简单任务。
  1. (可选)指定模型对话
claude --model qwen3.5-plus

上述的修改能覆盖command line + service调用(如pencil.dev),使用unix-like操作系统,windows配置文件路径不同,参见官方说明。

ref:

Feb 25, 2026
Tools

读书笔记-创新与企业家精神

《创新与企业家精神(珍藏版)》读书笔记总结

作者:彼得·德鲁克(Peter F. Drucker),1985年著

笔记自己在Readest边读边做的,导出给AI整理总结。


一、核心概念

什么是企业家精神?

德鲁克认为,企业家精神的本质是有目的、有组织的系统创新,而创新就是改变资源的产出。企业家精神是一种行动,而不是人格特征;它的基础在于观念和理论,而非直觉。任何有勇气面对决策的人,都能通过学习成为企业家。

什么是创新?

  • 创新就是通过改变产品和服务,为客户提供价值和满意度
  • 创新不一定必须与技术有关,甚至根本不需要是一个"实物"
  • 没有科技含量的社会创新或市场创新,往往机会更多、周期更短、效益更大
  • 创新是否成功,不在于新颖或巧妙,而在于能否赢得市场

二、创新机遇的七大来源

德鲁克提出了七大创新机遇来源,按可靠性和可预测性递减排列:

内部来源(前四个)

1. 意外事件(意外的成功或失败)

  • 管理层要对每次意外成功追问:它对我们有什么意义?会带领我们走向何方?如何将它转换成机会?
  • 意外失败(精心设计却仍失败的)往往预示着根本性变化和机遇
  • 💡 笔记:没有足够的信息渠道知道自己的意外性成功;机遇来了要配备最优秀的人

2. 不协调的事件(现实与预期之间的差距)

  • 当生产商抱怨顾客"不理性"时,就存在创新机遇
  • 💡 笔记:需求没有消除,只是转移了;你得"加入"进去,成为它,才能改造它

3. 程序需要(替换薄弱环节、提供欠缺的环节)

  • 一旦创新出现,立刻被视为"理所当然"并成为标准
  • 五项基本要素:不受外界影响的程序、薄弱环节、清晰目标、可界定的解决方案规范、“应该有更好方法"的共识

4. 产业和市场结构变化

  • 四个预警指标:产业快速增长、产量翻番后认知方式过时、运营方式迅速改变、独立群体出现
  • 💡 笔记:供大于求时需要产业结构改变;发现独立群,为他们提供垂直便利

外部来源(后三个)

5. 人口统计数据

  • 年龄分布比绝对人口数字更重要
  • 💡 笔记:年龄分布即市场分布,可以针对性定制

6. 认知的变化(“杯子半满” vs “杯子半空”)

  • 认知转变孕育重大创新机遇,需要接近创新领域并注意机遇

7. 新知识(科学与非科学)

  • 所需时间最长、最不可靠、最不可预测
  • 要求所有必要知识齐备、有清晰的战略定位,不能以"尝试心理"创新
  • 💡 笔记:客户的价值定义了创新,而非技术的强与弱;每个产业都有"窗口期”

三、创新的原则与禁忌

该做的

  • 始于对机遇的系统分析,走出去多看、多问、多听
  • 左右脑并用:既观察数字,又观察人的行为
  • 简单明了,目标明确,一次只做一件事
  • 从小规模开始,快速验证
  • 以获得领导地位为目标
  • 以市场为中心、为导向
  • 专注于自身长处

禁忌

  • 不要太聪明——创新必须能由普通人操作
  • 不要过于多样化,不要分心
  • 不要为未来创新,要为现在创新
  • 少涉足多个领域

关于风险

成功的创新者都相当保守,他们不是"专注于冒险",而是"专注于机遇",设法将风险化解到最低。


四、企业家战略

1. 孤注一掷

只有成功或失败,适用于极少数创新。

Feb 12, 2026
books

aliyun-ddns设置定时监控更新

获取程序

click-me
aliyun-ddns用rust写的,自己和朋友也一直在用,喜欢的话不留余力请star, 有问题和建议也希望您提个issue知会我下。

获取AccessKeyID和AccessSecret

  1. 登录: ak-console.aliyun.com
  2. 使用其中一种方法创建AK, secret大多都是创建的时候可见,注意保存
    1. 继续用主账号创建AK秘钥,点击,然后根据提示创建,阿里现在不是很推荐了(安全性问题)
      d87429f6a41d823f7934ecca213918b9
    2. 点击开始使用子用户AK,按照操作设置后,在 用户管理 添加用户,分配权限(注意权限),生成AK
      95ceb1aa9d52644a03d45737de14f411
      c4bc43ee5978875c5a0eebe945877c3c

配置aliyun-ddns

  1. 登录到 域名页面 ,设置子域名,步骤: 进入解析-> 添加记录 -> 设置子域名 保存
    b0a2bac2b6811cbe155750eaf1c36946
    42c7c13ba5dea7d20bff08fd486d9a34

  2. 回到程序aliyun-ddns,打开common_conf, 编辑config.yaml, 对于获取公网IP的无需变动
    3561667e6e02a56ebb6527b44d485c98

配置windows定时任务

  1. 打开控制面板找到管理工具
    8ae4fa46789c0da6133bc8d7eee56b9c
  2. 打开定时任务
    484d28c4fe334d15cbd4278f3a9a3152
  3. 下面的请看图片了
    e2c598e3f6071806da9e0623c1883d68
    065dd736333dd66d3b8d8a02a1a037ff
    574503dcb7e9d0846fa61144a6369710
    064228eb6639cb0463d3354f8ce37b65
    3f86a1cdf817595dbfb669f29b683fa8
  4. 关于运行情况,查看日志文件,默认由common_conf/log4rs.yaml控制,在程序根目录的logs下。这里控制着日志级别,debug运行后无错误提示,请改为info节省磁盘空间
    559fec3e31905027b8a89e1291bd1f16
    9ee9451f9e57a67456435ffa98cf25ce

配置linux定时任务

linux就是依赖自带的 crontab定时任务 ,只要程序配置与windows相同
参照上方Tutorial设置好crontab后,启动该程序的crontab指令可以如下(每5分钟检测一次)):

*/5 * * * * cd /path/to/program/ && ./aliyun-ddns_linux
Oct 14, 2019
MyProgram

读书笔记-原则

Ray·Dalio «原则»:

文章分成了三步,第一部是讲的瑞的生活, 从一无所有到福布斯名列前茅. 我相信读同一本书, 在不同的时候, 不同的人与不同生活经历背景下, 感悟都是不同的.

第一部分讲述了他一生的历程, 从独生子女到抱孙子, 从低谷到福布斯.

瑞从一个美国的中产阶级(似乎没有), 家庭对他影响是极大的, 从初中的时候开始体验赚钱的不易, 开始打零工送报纸. 我觉得每个小孩都必须要在这里年纪经历一些历练. 瑞在刚步入大学的时候, 失去了他最爱的人-他母亲的离世. 在大学的时候, 他对于经济学是无比热爱的, 找到有爱好的专业是十分重要. 毕业后经历了上班族到自主创业的工程, 文中提及多次他的起起伏伏, 最低谷的时候曾是一个人孤军奋斗, 也曾是背负骂名(1982年他对于公众预言一场萧条,但结果没有发生,导致他胜败名列, 钱财殆尽), 但依然在低谷重新走出来, 这是多么伟大的毅力.

第二部分讲的是他的生活原则, 这也是让我很震撼的部分所有, 也是解释了他如今成就的原因所在.

  • 我对其印象深刻的, 是其中讲到的”两个你”, 这在我之前的理解中, 是上帝视觉(还有一种说法, 是把自己当成一只宠物, 来自一本自制力的书籍). 瑞谈及的两个你, 也是大脑的两个层次, 一个较低的层次控制着情感, 我们的冲动, 情绪来自他. 而高级的那个, 他是理智的, 主要在一些理性的时候, 他才会现身. 他所描述的, 我们应该时刻提示自己这两个层次的存在, 当你情绪很失控的时候, 你要想到低级的大脑开始搞事情了,此时能做’想到’这件事的, 正是你高级的大脑做的. 我们需要在生活, 逐步的训练自己, 让高级的大脑灵活用起来. 在面临很多情绪化的问题的时候, 你需要马上高级大脑接管模式. 在生活训练他并不断强化.
  • 在痛苦中成长, 做进化的自己. 这与我的观点大抵是一致的, “不进则退”, 默认的认知中, 我们在对抗很多的一些改变, 能力上的, “不得不”学习新的东西, 新的编程, 新的公式逻辑, 新的环境, 新的概念等, “人类总是恐惧未知的东西”, 但是否真的想要前进, 这决定着是否要迎接改变. 在痛苦成长, 而瑞把痛苦当然粮食, 他觉得痛苦意味着是前进的步伐, 啃食痛苦, 反思痛苦, 从而改善然前进.
  • 做到头脑”极度开放”, 这似乎是瑞终生的信条了, 但这确实很抽象. 这蕴含在任何领域都是方方面面的, 对真诚的渴望, 对生活的上进, 对为人处世的心胸开旷等等, 如果我哪天能做到这样子, 大概也是一帆况景了.

第三部分是工作的原则, 这直接的成就让他当前的企业拥有了成就并步入福布斯, 而企业的话题总是文化-制度, 他曾是企业的顶梁柱, 一切的标准所在. 我也不曾是一个管理的身份, (如果说做到班长算是有管理经验的话另说). 以下是我在文章看到并走进脑子思考的部分.

Jun 20, 2018
books

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