基于深度学习的胸部 X 光图像肺炎分类系统(二)

 本文主要说明神经网络的构建,共21个层级

def build_model(input_shape):

    model = models.Sequential([

        layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),

        layers.BatchNormalization(),

        layers.MaxPooling2D((2, 2)),

        layers.Dropout(0.2),

        layers.Conv2D(64, (3, 3), activation='relu'),

        layers.BatchNormalization(),

        layers.MaxPooling2D((2, 2)),

        layers.Dropout(0.3),

        layers.Conv2D(128, (3, 3), activation='relu'),

        layers.BatchNormalization(),

        layers.MaxPooling2D((2, 2)),

        layers.Dropout(0.4),

        layers.Conv2D(256, (3, 3), activation='relu'),

        layers.BatchNormalization(),

        layers.MaxPooling2D((2, 2)),

        layers.Dropout(0.5),

        layers.Flatten(),

        layers.Dense(512, activation='relu'),

        layers.BatchNormalization(),

        layers.Dropout(0.5),

        layers.Dense(1, activation='sigmoid')

    ])

    optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

    model.compile(

        optimizer=optimizer,

        loss='binary_crossentropy',

        metrics=[

            'accuracy',

            tf.keras.metrics.Precision(name='precision'),

            tf.keras.metrics.Recall(name='recall'),

            tf.keras.metrics.AUC(name='auc')

        ]

    )

    return model

神经网络工序

咱们数一下这个神经网络总共有多少层(按代码里的顺序一层一层数):

  1. Conv2D(32, ...) → 第 1 层(卷积层)
  2. BatchNormalization() → 第 2 层(标准化层)
  3. MaxPooling2D(...) → 第 3 层(池化层)
  4. Dropout(0.2) → 第 4 层(dropout 层)
  5. Conv2D(64, ...) → 第 5 层(卷积层)
  6. BatchNormalization() → 第 6 层(标准化层)
  7. MaxPooling2D(...) → 第 7 层(池化层)
  8. Dropout(0.3) → 第 8 层(dropout 层)
  9. Conv2D(128, ...) → 第 9 层(卷积层)
  10. BatchNormalization() → 第 10 层(标准化层)
  11. MaxPooling2D(...) → 第 11 层(池化层)
  12. Dropout(0.4) → 第 12 层(dropout 层)
  13. Conv2D(256, ...) → 第 13 层(卷积层)
  14. BatchNormalization() → 第 14 层(标准化层)
  15. MaxPooling2D(...) → 第 15 层(池化层)
  16. Dropout(0.5) → 第 16 层(dropout 层)
  17. Flatten() → 第 17 层(展平层)
  18. Dense(512, ...) → 第 18 层(全连接层)
  19. BatchNormalization() → 第 19 层(标准化层)
  20. Dropout(0.5) → 第 20 层(dropout 层)
  21. Dense(1, ...) → 第 21 层(输出层)

这个神经网络总共是 21 ,可以分成几类:

  1. 卷积层(提取图片特征):4 层
  2. 标准化层(让特征更稳定):5 层
  3. 池化层(压缩信息):4 层
  4. Dropout 层(防止死记硬背):4 层
  5. 展平层(整理特征):1 层
  6. 全连接层(综合判断):2 层(最后一层是输出层)

卷积层

Conv2D 是神经网络里专门用来 “看图片” 的 “放大镜工具”,全称是 “二维卷积层”,特别擅长从图片中抓特征(比如边缘、斑点、纹理这些)。

假设你有一张 X 光片,Conv2D 就像一个小窗口(比如 3x3 像素大小),会从图片左上角开始,一点点往右、往下滑动,每到一个位置就 “扫描” 这个小窗口里的像素,计算出一个新的数值 —— 这个数值就代表了这个区域的某个特征(比如 “这里有一条边缘”“这里有块阴影”)。

代码里的 Conv2D(32, (3, 3), ...) 可以拆成两部分理解:

  1. 32:表示同时用 32 个不同的 “放大镜”(每个放大镜侧重抓不同的特征,比如有的专门找横线,有的找圆点,有的找模糊阴影)。
  2. (3, 3):每个放大镜的窗口大小是 3x3 像素(就像用一个 3x3 的小方格去扫图片)。

经过 Conv2D 处理后,一张图片会变成 32 张 “特征图”—— 每张特征图上都是用对应的 “放大镜” 抓出来的特征,方便后面的层进一步分析。

简单说,Conv2D 的作用就是:用多个小窗口扫描图片,把隐藏的特征(比如肺炎的阴影)显形”,是神经网络 “看懂” 图片的核心工具。

固定窗口与自动学习的卷积核

(3, 3) 这个卷积窗口大小是程序员提前设定好的固定值,不是自动计算或随机生成的。它就像一个 “标准工具尺寸”,是人为选定后写死在代码里的。

而 32 个卷积核(“放大镜”)的具体识别能力,则是在训练过程中学” 出来的,不是一开始就固定的:

  1. 刚开始时,这 32 个 (3,3) 的卷积核都是 “空白” 的,不知道该识别什么特征(比如横线、阴影)。
  2. 当网络开始 “看” 大量 X 光片时,会根据图片内容和判断对错的反馈,自动调整每个卷积核的参数。
  3. 最后会自然分化出不同分工:有的卷积核擅长找边缘,有的擅长抓斑点,有的对阴影敏感 —— 就像 32 个学生通过练习,各自练出了不同的 “看片绝活”。

简单说:

  1. (3,3) 的窗口大小是 “人为定好的工具规格”;
  2. 32 个卷积核如何用这个窗口识别特征,是 “通过学习练出来的本事”。

整个过程就像:老师先规定 “必须用 3×3 厘米的放大镜观察”(固定窗口),然后让 32 个学生用这个工具去看大量图片,最后每个学生自然练出了不同的观察重点(自动学到不同特征)。

神经网络辅助工具的黄金搭档

这三行代码是神经网络里的 “辅助工具”,配合前面的卷积层一起工作,让网络学得更好、更稳定。用大白话一个个解释:

1. layers.BatchNormalization()

可以理解成 “数据标准化工具”,作用是让每层处理的数据 “保持稳定”。

比如:

  1. 不同 X 光片的亮度可能差很多(有的亮、有的暗),经过它处理后,会把亮度统一到一个合理范围。
  2. 就像老师批改作业时,先把不同学生的字迹大小、卷面整洁度 “标准化”,再公平打分,避免因为数据本身的差异影响学习效果。

简单说:让数据更规整,网络学起来更轻松

2. layers.MaxPooling2D((2, 2))

“压缩工具”,专门给图片 “瘦身”,保留关键信息的同时减少计算量。

(2, 2) 表示把图片按 2x2 的小方块划分,每个方块里只保留最亮(数值最大)的那个像素,其他的丢掉。

比如:

  1. 一张 100x100 的图片,经过它处理后会变成 50x50(直接缩小一半)。
  2. 就像把一张高清照片缩印成小照片,虽然变小了,但主要内容(比如大的阴影、边缘)还在,却能节省很多存储和计算的力气。

简单说:去粗取精,让网络跑得更快

3. layers.Dropout(0.2)

“防作弊工具”,故意让一部分 “神经细胞” 暂时 “休息”,避免网络 “死记硬背”。

0.2 表示随机让 20% 的细胞不工作。

比如:

  1. 网络可能会 “偷懒”—— 只记住某张 X 光片的特殊标记(比如角落的污渍)而不是真正的肺炎特征。
  2. dropout 就像考试时故意遮住一部分题目,逼网络真正理解知识(肺炎的通用特征),而不是靠死记硬背蒙混过关。

简单说:防止学歪,让网络更会举一反三

这三个工具是卷积层的 “黄金搭档”:

  1. 标准化让数据更规矩,
  2. 池化让计算更高效,
  3. Dropout 让学习更扎实,

Dropout 的作用与避免过拟合

layers.Dropout(0.2) 就像给神经网络 “故意制造一点小麻烦”,防止它 “死记硬背” 答案。

原理:故意 “关掉” 一部分神经细胞

  1. 0.2 意思是:每次训练时,随机让 20% 的 “神经细胞” 暂时 “休息”(不工作、不参与计算)。
  2. 比如有 100 个细胞,每次会随机挑 20 个 “放假”,剩下 80 个干活。下次训练再换另外 20 个放假,完全随机。

这么做的目的是:逼网络学通用规律”,而不是 “死记硬背”

举个例子:

如果网络学 X 光片时,发现 “某张肺炎片角落有个小黑点”,没 dropout 的话,它可能偷懒只记 “有小黑点就是肺炎”(其实那是污渍)。

但有了 dropout(随机关掉部分细胞),它没法总依赖 “小黑点” 这个特征(因为记这个特征的细胞可能被关掉),只能被迫去学更靠谱的规律(比如阴影的形状、分布)。

不用它会有什么问题?

最容易出现的问题是 “过拟合”—— 网络把训练时的图片 “背得滚瓜烂熟”,但换一张新图片就傻了。

比如:

  1. 训练时的肺炎片都有 “左边有阴影” 的特点,网络就死记 “左边有阴影 = 肺炎”。
  2. 遇到一张新的肺炎片(右边有阴影),它就会判断错,因为没学过 “右边阴影也是肺炎” 的通用规律。

没有 dropout 的网络,就像死记硬背考试答案的学生 —— 考题稍变就不会做了;

有 dropout 的网络,就像真正理解知识点的学生 —— 不管题目怎么变,都能答对。

Dropout(0.2) 就是通过 “随机让 20% 细胞休息”,防止网络 “走捷径、死记硬背”,逼着它学更通用的规律,这样面对新图片时判断更准。

不用它,网络容易 “学傻”,只会应付老图片,不会处理新情况。

全连接层:神经网络里的 “全面沟通层”

 

        假设前面的卷积层是 “侦察兵”,各自盯着图片里的小细节(比如边缘、颜色块、纹理),每个侦察兵只负责自己那一小块信息。

 

        到了全连接层,就像把所有侦察兵召集到一个大会议室。这一层里的每个 “决策者”(神经元)都会和所有侦察兵聊一遍 —— 也就是接收前面所有层的信息,一个都不落下。

 

比如识别猫的时候:

 
  • 有的侦察兵看到 “三角形耳朵”,有的看到 “毛茸茸的纹理”,有的看到 “竖起来的尾巴”。
  • 全连接层的 “决策者” 会把这些信息全汇总起来,判断 “这些特征加起来是不是一只猫”。
 

之所以叫 “全连接”,就是因为这一层的每个神经元和上一层的所有神经元都有连接,没有信息死角。它的作用就是把零散的细节拼成一个完整的判断。

layers.Dense(512, activation='relu'):

  • Dense:就是 “全连接层”,意思是这一层的每个 “神经细胞” 都会和上一层所有的特征产生连接,就像一个会议室里,每个专家都要听取前面所有人的汇报。
  • 512:表示这个 “整合中心” 有 512 个 “专家”(神经细胞),每个专家负责关注不同的特征组合(比如 “阴影形状 + 位置”“边缘清晰度 + 大小”)。
  • activation='relu':相当于 “过滤器”,只让有价值的特征组合通过(比如 “这个阴影形状很可能是肺炎”),过滤掉无意义的信息(比如 “图片角落的小噪点”)。

神经网络的决策层

这部分是神经网络的 “决策层”,负责把前面提取到的图片特征汇总起来,最终判断 “是不是肺炎”。用大白话一个个解释:

1. layers.Flatten()

“整理工”—— 把前面层层处理得到的特征(像一堆二维的矩阵)全部摊平,变成一条长长的 “特征数字链”。

比如:前面最后一层可能输出一个 7×7×256 的特征矩阵(类似一堆叠起来的小图片),经过 Flatten() 处理后,会变成一个 7×7×256=12544 个数字组成的一维列表。

作用:把复杂的多维特征 “捋顺”,方便后面的 “决策专家” 处理。

2. layers.Dense(512, activation='relu')

“特征整合专家团”——512 个 “专家” 一起分析前面摊平的特征链,找出最关键的信息。

  1. 512:表示有 512 个 “专家”(神经元),每个专家负责关注不同的特征组合(比如 “阴影形状 + 位置”“边缘清晰度 + 大小”)。
  2. relu:激活函数,相当于 “过滤器”,只让有价值的特征组合通过(过滤掉无意义的信息)。

作用:把零散的特征(比如 “有阴影”“边缘模糊”)整合成更高层次的判断依据(比如 “这些特征组合起来像肺炎”)。

3. layers.BatchNormalization()

“稳定器”—— 和前面卷积块里的作用一样,让 512 个专家的 “意见” 更统一、更稳定。

比如:避免某个专家因为特征数值波动(比如某次特征值特别大)而过度影响结果,让判断更可靠。

4. layers.Dropout(0.5)

“防偏见工具”—— 随机让 50% 的 “专家” 暂时不发表意见,防止网络过度依赖某几个专家的判断。

比如:如果某个专家错误地认为 “所有圆形阴影都是肺炎”,dropout 会偶尔让它闭嘴,逼网络参考其他专家的意见,避免 “偏见” 影响最终结果。

5. layers.Dense(1, activation='sigmoid')

“最终裁判”—— 综合所有专家的有效意见,给出最终结论。

  1. 1:只有 1 个 “裁判”,负责输出最终结果。
  2. sigmoid:激活函数,把结果压缩到 0~1 之间 —— 越接近 0 表示 “越可能正常”,越接近 1 表示 “越可能是肺炎”。

作用:给出一个明确的二分类判断(是 / 不是肺炎)。

这部分就像 “医院会诊” 流程:

  1. Flatten() 把前面检查到的各种细节(特征)整理成报告;
  2. Dense(512) 一群医生(专家)讨论报告,找出关键信息;
  3. 标准化和 Dropout 确保讨论公平、客观;
  4. 最后 Dense(1) 由主任医师(裁判)给出 “是肺炎” 或 “正常” 的最终诊断。

决策层中的数据标准化小助手

layers.BatchNormalization() 可以理解成神经网络里的 “数据标准化小助手”,作用是让每层处理的数据 “保持稳定”,避免因为数据忽大忽小给网络添乱。

举个生活例子:

假设你在玩拼图,前几包拼图的碎片都是 5 厘米大小,突然来了一包 5 米大的碎片 —— 你肯定会懵,不知道怎么拼。

神经网络也一样,如果上一层输出的数据忽大忽小(比如一会儿是 0.1、0.2,一会儿是 100、200),下一层就会 “confusion”,学起来很费劲。

BatchNormalization 就像一个 “调解员”:

它会把每层的数据 “重新整理” 一下,让数据都集中在一个合理的范围(比如大部分在 0 附近波动),不会出现特别大或特别小的极端值。

比如:

  1. 处理图片时,有的像素亮度是 10,有的是 200,差距很大;
  2. 经过它处理后,会把亮度统一调整到 “-1 到 1 之间”,让网络能更专注于学习特征(比如阴影形状),而不是被数据本身的大小干扰。

简单说:它让数据变得 “规矩”,让网络学起来更轻松、更稳定,不容易因为数据波动而 “学偏”。

神经网络的学习规则设定

    # 使用更稳定的优化器
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

    model.compile(
        optimizer=optimizer,
        loss='binary_crossentropy',
        metrics=[
            'accuracy',
            tf.keras.metrics.Precision(name='precision'),
            tf.keras.metrics.Recall(name='recall'),
            tf.keras.metrics.AUC(name='auc')
        ]
    )

这部分代码是给神经网络 “设定学习规则”,就像给学生制定 “学习方法” 和 “考试标准”。

1. optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

学习节奏控制器”

  1. Adam 是一种聪明的 “学习方法”(优化器),就像一个有经验的老师,会根据学生的答题情况调整教学节奏。
  2. learning_rate=0.0001 是 “步长”,表示每次调整的幅度。比如学生做题错了,老师不会一下子全盘否定(步长太大),也不会完全不调整(步长太小),0.0001 是个 “适中的小步调整”,让学习更稳。

作用:让网络在训练时,能慢慢修正错误,找到正确的 “判断规律”。

2.将优化器交给模型

optimizer=optimizer 看起来像绕口令,其实很简单:就是把前面定义好的 “学习方法”(那个叫 Adam 的优化器)正式 “交给” 模型。

打个比方:

  1. 你先买了一支好用的笔(optimizer = tf.keras.optimizers.Adam(...)),这支笔就是你的 “写字工具”;
  2. 然后你告诉模型:“来,用这支笔写字”(optimizer=optimizer),这里第一个 optimizer 是模型要求的 “参数名”(固定写法),第二个 optimizer 就是你前面买的那支笔。

说白了,就是把准备好的 “学习节奏控制器” 正式安装到模型里,让模型训练时能按这个方法调整自己的 “学习策略”。

3. model.compile(...)

设定训练目标和评分标准”

就像告诉学生:“这次训练要达到什么目标,用什么标准判断你学得好不好”。

  1. loss='binary_crossentropy'错题本”

二分类任务(比如 “是肺炎” 还是 “不是肺炎”)的专用 “错题计算方式”。值越小,说明网络当前的判断和实际结果越接近(错题越少)。

  1. metrics=[...]考试评分项”

用来衡量网络学得好不好的具体指标(相当于考试的不同题型得分):

    1. accuracy(准确率):总共判断对了多少(对的 ÷ 总题数)。
    2. precision(精确率):说 “是肺炎” 的案例中,真的是肺炎的比例(避免 “狼来了” 式误判)。
    3. recall(召回率):所有真肺炎案例中,成功找出来的比例(避免漏诊)。
    4. auc:综合判断能力的评分(0.5 是瞎猜,越接近 1 越好)。

这部分代码的作用是:

  1. 给网络选一个 “聪明的学习方法”(Adam),设定合适的 “调整步长”(0.0001);
  2. 明确 “怎么算错”(loss)和 “怎么算学得好”(metrics)。

就像给学生说:“用这种方法慢慢学,错了就小幅度改,最后我会从准确率、漏诊率等几个方面给你打分”。

21层是怎么来的:

这个 21 层的设计不是随便拍脑袋定的,而是像 “搭积木盖房子” 一样,根据 “要解决的问题(识别 X 光片)” 和 “经验规律” 一点点堆出来的。咱们用大白话讲清楚:

先想明白:盖这个 “房子” 是为了啥?

目标是让电脑能看懂 X 光片,区分 “正常” 和 “肺炎”。X 光片里有很多细节(比如阴影的形状、边缘),需要一层层处理:

  1. 先抓简单特征(比如有没有边缘、小块阴影)
  2. 再组合成复杂特征(比如阴影的整体形状)
  3. 最后判断是不是肺炎

就像医生看片:先看局部细节,再拼出整体印象,最后下结论。层数太少可能 “看不清楚”,太多又 “浪费力气”。

21 层的设计逻辑:跟着问题需求走

咱们拆成几部分看为什么这么设计:

1. 4 个 “卷积块”(每个块 4 层,共 16 层)—— 为了 “看清楚细节”

每个卷积块都是 “Conv2D + 标准化 + 池化 + Dropout” 的组合(4 层),为什么要 4 个这样的块?

  1. 第一层(Conv2D:用 “放大镜” 找特征。数字从 32→64→128→256,是因为:

一开始用少点 “放大镜”(32 个)找简单特征(比如边缘);

后面用更多 “放大镜”(256 个)找复杂特征(比如阴影的纹理、形状)。

  1. 中间两层(标准化 + 池化):标准化让特征更稳定(比如不同亮度的片子能公平比较),池化把图片缩小(节省计算力,只留关键信息)。
  2. 最后一层(Dropout:比例从 0.2→0.5 越来越大,因为学的特征越来越复杂,更要防止 “死记硬背”(比如只记某张图的特殊标记)。

用 4 个块,是因为 X 光片的特征不算特别复杂,但也需要逐步深入 —— 就像剥洋葱,一层一层剥开才能看到核心。

2. 分类器部分(5 层)—— 为了 “下结论”
  1. Flatten :把前面的特征 “摊平” 成一条线,方便后面的 “判断专家” 处理(1 层)。
  2. Dense(512):512 个 “专家” 综合所有特征讨论(比如 “这个阴影形状像肺炎”“边缘不清晰可能不是”)(1 层)。
  3. 标准化 + Dropout:让专家讨论更理性,避免极端意见(2 层)。
  4. 最后一层 Dense (1):给出最终结论(0~1 之间的数字,判断是不是肺炎)(1 层)。

这部分层数少,因为前面的特征已经提取得差不多了,只需要集中做一次判断。

为什么是 21 层?不是 10 层或 30 层?

  1. 不是固定公式:没有 “必须 21 层” 的规定,就像盖房子,3 层能住,5 层也能住,看需求。
  2. 经验为主:人们发现处理这类 X 光片(中等复杂度的图片),用 4 个卷积块(16 层)+ 简单分类器(5 层)比较合适:
    1. 少于 10 层:可能 “看不透” 细节(比如小的肺炎阴影抓不到)。
    2. 多于 30 层:电脑要算很久,还可能 “想太多”(把正常的纹理当成肺炎特征)。
  3. 试出来的:程序员可能一开始试了 10 层,发现效果不好(漏诊多);又试了 30 层,发现太慢还容易错;最后调到 21 层,效果和效率比较平衡。

21 层的设计就像 “定制眼镜”:

  1. 层数和结构是根据 “看 X 光片” 这个任务的难度定的;
  2. 从简单到复杂逐步提取特征,既不会 “看不清”,也不会 “想太多”;
  3. 是程序员根据经验和测试结果,一点点调整出来的 “平衡方案”,不是固定答案。

就像做饭的菜谱,盐放多少、炒多久,是根据食材和口味慢慢试出来的,没有绝对的 “必须”,只有 “合适”。

X光片诊断神经网络

:这个函数是在给电脑搭建一个 “识别 X 光片的大脑”,专门用来判断片子是 “正常” 还是 “肺炎”。

原理

这个 “大脑” 叫 “卷积神经网络(CNN)”,特别擅长看图片。它的工作方式有点像医生看片:

  1. 先看整体轮廓(比如有没有大片阴影)
  2. 再看细节(比如阴影的形状、位置)
  3. 最后综合判断是不是肺炎

整个 “大脑” 是一层一层叠起来的,每一层有不同的分工,就像工厂的流水线一样,一步步把图片信息变成 “正常” 或 “肺炎” 的判断。

逐部分解释代码

1. 搭 “大脑” 的架子

model = models.Sequential([...])

  1. Sequential 表示 “按顺序叠层”,就像搭积木一样,一层摞在另一层上面。
  2. 中括号 [...] 里的内容,就是一层一层的 “积木”(神经网络层)。
2. 第一层:先抓图片的细节特征

layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),

  1. 这是 “卷积层”,相当于给电脑装 “放大镜”,专门找图片里的细节(比如边缘、斑点、阴影)。
  2. 32:表示用 32 个不同的 “放大镜”(每种放大镜找不同的特征,比如有的找横线,有的找圆点)。
  3. (3, 3):每个放大镜的大小是 3x3 像素(小窗口慢慢扫过图片)。
  4. activation='relu':相当于 “过滤器”,只保留有用的特征(把不重要的信息丢掉)。
  5. input_shape:告诉电脑输入的图片是什么样的(比如 150x150 的彩色图)。
3. 第二层:让特征更稳定

layers.BatchNormalization(),

  1. 相当于给特征 “做标准化”,让电脑更容易学(比如把亮度不一的图片调成差不多的亮度)。
4. 第三层:压缩信息,去粗取精

layers.MaxPooling2D((2, 2)),

  1. “池化层”,把图片缩小一半(比如 150x150 变成 75x75),只保留每个区域里最明显的特征。
  2. 就像把一张画缩印,虽然变小了,但主要内容还在,还能节省电脑的力气。
5. 第四层:故意 “忘记” 一些信息

layers.Dropout(0.2),

  1. 随机让 20% 的 “神经细胞” 休息,防止电脑 “死记硬背”(比如只记住某张图的特殊标记,而不是真正的肺炎特征)。
  2. 就像学生背书时故意遮住几个字,逼自己理解意思而不是死记。
6. 重复几次 “卷积 - 标准化 - 池化 - dropout”

后面还有 3 组类似的层:

# 第二组

layers.Conv2D(64, (3, 3), activation='relu'),

layers.BatchNormalization(),

layers.MaxPooling2D((2, 2)),

layers.Dropout(0.3),

# ... 还有两组

  1. 每组的 Conv2D 数字从 32→64→128→256,意思是 “放大镜” 越来越多,能抓的细节越来越丰富。
  2. Dropout 从 0.2→0.3→0.4→0.5,意思是 “忘记” 的比例越来越高,防止死记硬背的效果更强。
7. 把图片压成一条线

layers.Flatten(),

  1. 经过前面的处理,图片已经变成了一堆 “特征”,这一步把它们排成一条直线,方便后面的层处理。
  2. 就像把叠好的衣服摊开,一件件数清楚。
8. 综合判断(全连接层)

layers.Dense(512, activation='relu'),

layers.BatchNormalization(),

layers.Dropout(0.5),

  1. Dense(512):相当于 512 个 “判断专家”,每个专家根据前面的特征发表意见(比如 “我觉得这是肺炎”)。
  2. 后面的标准化和 dropout 和前面作用一样,让判断更稳定、更灵活。
9. 最终结论

layers.Dense(1, activation='sigmoid')

  1. 最后一个 “专家” 综合所有意见,给出最终结果:
    1. 输出 0~1 之间的数字,越接近 0 越可能是 “正常”,越接近 1 越可能是 “肺炎”。
    2. sigmoid 是一种计算方式,保证结果在 0~1 之间。
10. 教 “大脑” 怎么学习

optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)

model.compile(

    optimizer=optimizer,

    loss='binary_crossentropy',

    metrics=[...])

  1. optimizer:学习方法,这里用 “Adam”(一种高效的学习方式),learning_rate=0.0001 是 “学习速度”(不能太快,不然学不扎实)。
  2. loss='binary_crossentropy':判断错了怎么 “惩罚”(比如把肺炎认错成正常,就多罚一点)。
  3. metrics:学习时要关注的指标(比如准确率、精确率等,相当于考试的评分标准)。

这个函数搭建的 “大脑” 就像一个 “X 光片诊断流水线”:

  1. 先用多层 “放大镜” 找特征(卷积层)
  2. 不断压缩信息、去粗取精(池化层)
  3. 防止死记硬背(dropout)
  4. 最后综合所有特征给出判断(全连接层)

搭好后,这个 “大脑” 就可以开始学习了 —— 通过看大量标好的 X 光片,慢慢学会区分正常和肺炎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值