为什么我要写这个教程

因为写教程, 教会其他人, 是学习的一部分, 也是学习过程中最为重要的一部分.

不论是学习编程还是学习看病还是学习做手术都是这样. 作为眼科医生, 回忆一下你在住院医阶段记得最清楚的几个疾病, 是不是你被要求在查房时讲解的哪些, 印象最深的病人, 是不是你刚开始管病人时被问住的哪些.

只有教会了其他人, 学习的过程才算是完整的.

我现在正在学习python, 进一步我还在深入学习"深度学习", 还打算使用python和深度学习技术做很多有意思的东西. 为了自己的学习, 也为了让大家也能体会到这些乐趣, 我开始写这个教程.

本教程特点

python的教程很多很多, 有些非常好, 有些非常坑, 我会按照自己的经历参考和重新编排这些教程, 产生这个新的面向眼科医生的python教程.

我启动学习python已经很多次, 只有最后这一次坚持下来了. 我深知学习过程中容易放弃的原因, 因此我会在本教程中尽量使眼科医生能够快速上手, 迅速产生实用的效果, 躲开一些python程序员引以为傲的奇技淫巧与晦涩难懂的区域.

本教程中, 会尽量贴近眼科中常见的场景, 编写一些能够在日常工作中可用的代码. 本教程中会尽快进入科学计算部分, 具体的内容参考后面课程大纲.

此处面向专业程序员解释, 未学编程的眼科医生不必费心理解:

  • 我会优先讲解numpy array, 跳过List, set, dict等数据结构, 在迫不得已时才引入;
  • 我会优先使用向量化, 在迫不得已时才引入循环;
  • 我会优先讲解基于Google/ Stack overflow和各种现成工具包的编程, 而不是自己从零开始写代码;

为什么要学编程

点击下面这个视频, 先看一段非眼科"成功人士"对为什么要学编程的理解:

每个人的动机可能会有不同. 我不知道你第一次拿起手术刀, 第一次坐在显微镜之前, 第一次听见Phaco机的鸣唱, 第一次独立完成一个手术是什么感觉. 我第一次学习编程的时候, 会有类似的感觉.

我记得我是初一才开始学习编程, 写的第一个程序是计算从1+2+3... 99+100, 常年参加数学竞赛的我当然知道$\frac{(1+100)\times 100 }{2}=5050 $, 但是看到计算机若无其事地从1加到了100, 并且返回了5050的结果以后. 我意识到我所能达到的边界被极大扩展了, 原本必须使用复杂技巧绕过的障碍, 突然之间不复存在.

这种震撼的感觉在我少年时期出现过三次: 第一次接触到解方程, 第一次编写程序和第一次理解进化论是一种算法.

为什么眼科医生要学习编程

就像我在其他很多文章中所写的. 如果你想在眼科作出什么成就, 你会发现所需要的知识一定不在眼科书上. 当你想自己做点研究, 你会发现多数你想到的东西已经被人做过了, 如果你发现还有什么没人做过的, 通常是你查文献还不够深入. 全球有不止70亿人, 其中也有无数的眼科PhD, 相当多的题目都已经被做了, 很多还已经做得很完善.

那么还剩下哪些能做的东西呢? 能够做的题目可以总结为: 天时地利人和

  • 人和, 中国大陆拥有最多的人口, 所以大量的流行病学调查是可以在国内做的, 如果联合几个大的眼科中心, 那么能够做出多中心大规模的临床实验.
  • 地利, 有些研究, 还是可以做个"国内领先", "省内领先", "市内领先", 但不知道这样的有啥意思.
  • 天时, 在我看来这个才是最有意义的问题: 轮子为什么没有在轮子被发明之前被发明?
    • 很多时候一个技术或者一个科学, 之所以没有出现是因为技术水平不成熟.
      • 光场的文献最早出现与1908年, 直到2006年才有Lytro推出光场相机, 结果还卖得不好, 差点没倒闭.
      • 人工神经网络的研究从196x到198x就有了, 即使是卷积神经网络也在199x年出现过, 2012年AlexNet才真正开始认识猫
      • OCT的原理是干涉仪, 就是在高中学过证明以太不存在的迈克耳孙-莫雷实验 这个实验是1887年做的, OCT是哪年进入贵院?
    • 以上这些研究虽然开始都很早, 但真正做出东西却很晚, 原因不外乎没有计算机, 计算机速度不够快, 缺少激光, 缺少CCD. . . 也就是缺少一些关键技术
    • 反过来看, 如果具有了某项关键技术, 那么以前不可能的事情就会变得可能起来, 以前做不了做不到的事情就能做了.
    • 那么要找到过去没有现在有了的关键技术, 显然还是计算机IT领域, 而当你想要利用上IT技术, 你得先学会操纵计算机, 也就是编写程序.

眼科需要处理的数据更复杂

眼科里能够采集到的数据是很多很复杂的, 这一点其他科比不了. 其他科室很少有能够采集到大量原始数据的, 比如内科靠听, 但他们很少能真正录下来一段心音肺音, 都是用各种名词来描述, 也就是用人力先处理了一遍; 普外靠摸, 但现代科技连触觉怎么采集怎么记录怎么重现都还没搞清楚; 而我们眼科靠看, 看的东西用相机照下来就是原始数据啊.

但是原始数据的处理是很复杂的, 数理统计里面大多数情况下是在统计单一一个数字的变化, 不管你是用SPSS还是SAS, 做ANOVA还是Logistic回归, 通常能处理的变量个数也就是个位数的. 但对于图片, 能看清至少得100 x 100的像素吧, 一下就是10000个数, 很难交给常规的统计软件处理. 所以有些东西得自己写.

深度学习与眼科

2012年发生了一件大事, 一个叫做AlexNet的程序可以比较准确地识别图片了, 用了一类叫做深度学习的技术. 从此以后深度学习一年比一年热, 人工智能的概念也重新回归, 接着围棋人类也输了.

深度学习技术, deep learning, 最擅长的就是处理图像. 而医疗领域里, 用图像最多的, 可能就是我们眼科了, 我觉得比放射科和病理科还多. 眼科是非常适合使用深度学习的临床学科.

因此, 可以看到:

这个列表还会逐渐增长, 要理解和掌握深度学习, 甚至哪怕是为了与相关学科的学者和工程师沟通, 眼科医生也需要掌握一些基本的编程概念. 编程是一种外语.

我已经不是学生了还学啥

也许你已经是主治/副主任/主任医师了.

眼科医生一直是多才多艺的. 我记得我刚进眼科的时候, 发现老教授用五笔字型打字比我输入快得多, 我刚开始在网上学公开课的时候, 老教授已经在研究Coursera并且推动眼科MOOC了.

眼科医生当然是需要终身学习的.

女医生也可以学编程么?

最伟大的程序员是女性. 当我们说某个领域最伟大的人时, 唯一没有争议的提法, 就是开创这个领域的人.

第一位程序员, 是埃达·洛夫莱斯

同理, 最伟大的眼科医生是赫尔曼·冯·亥姆霍兹 他发明了眼底镜, 此后眼科才独立成为一个学科. 虽然Allvar Gullstrand 发明了裂隙灯而且霸气地干掉了相对论的诺贝尔奖, 但那时候眼科已经独立存在了.

一个人是不应该被简单的词汇所限定住, 你做什么或者不做什么, 只有自己才能决定.

何况学习编程只需要一台电脑甚至手机就可以了. 不试试么?

我应该如何学习编程

如何学好和如何学坏是一样的:

  • 被一些快感所诱惑
  • 快速上手, 逐步深入, 获得快感的正反馈
  • 传播, 让周围的人一起

为什么要学Python

人多

python使用人数 这是StackOverFLow上统计的近年来使用各个计算机语言的程序员数量. 可以看出python一直成直线上升, 并且已经成为最受欢迎的语言.

用的人多就意味着这种语言有大量的教程, 有良好的社区支持, 有什么深坑浅坑都已经有人踩过了, 并且放在了stackoverflow上或者可以被google轻易搜索到.

免费开源

python是免费并且开源的, (这两者略有差别). 在科学计算领域还有MatLab, Mathematica等数学软件也很好用, 但价格并不便宜, 使用盗版提心吊胆, 安装起来也不轻松.

从科学研究的角度来说, 科研就是开放源代码的, 实验数据应当可查证, 实验过程要公开详细, 能够被同行评议. 涉及到科研的计算工具其实也应当尽量是开放源代码的, 计算过程可以被同行评议. 否则埋藏很深的计算bug实验失败就很痛苦了.

先进技术用得多

python有大量的扩展包. 随着教程的进行, 我会开始import各种扩展包, python的package就像是强大的武器库, 甚至很可能你需要的一个功能, 早已经有人做好了相应的package放在网上了等着用了. 这其中有相当多的是与科学计算有关的.

python之所以这几年迅速流行, 我认为跟云计算, 大数据与机器学习的兴起有关.

这三件事情是紧密相关的, 最终的结果是你可以用便宜的价格租用一台网上的虚拟计算机, 就像我推荐使用的cocalc.com, 这台计算机通常是内置python的.

工业界主流用来编写深度学习软件的语言就是python, tensorflow/ pytorch/ keras都是基于python的. 可以说目前最新最热的领域就是建立在python之上.

简单

python是一种解释型动态高级语言. 就是说它不需要去理会一些诸如内存分配回收的系统相关问题. 相对于C/C++来说要简单很多. 以至于有"人生苦短, 我用python"的说法(参考: 人生苦短,我用Python. 一门编程语言的发展简史 )

当然从简单易学角度还会有其他更简单的语言, 例如p5.js, 但在实用与简单的平衡性上来说, python是比较好的.

课程大纲

Jupyter环境的使用

  • 熟悉CoCalc
  • 熟悉文学式编程
  • git初步

计算IOL度数的SRK公式计算器

  • 理解变量赋值
  • 函数定义

计算IOL度数的SRK II公式计算器

  • 分支结构

拟合自己的IOL公式

  • 导入numpy
  • numpy array
  • 读写excel数据
  • 循环与List
  • tensorflow初步

EDTRs视力表

  • 图像处理与OpenCV初步
In [ ]: