毕设项目分享 深度学习 opencv 公式识别

基于深度学习的数学公式识别毕设分享


0 前言

分享优质毕业设计项目,今天要分享的是

🚩 基于深度学习的数学公式识别算法实现

项目运行效果:

毕业设计 深度学习的公式识别

🧿 项目分享:见文末!



1 课题说明

手写数学公式识别较传统OCR问题而言,是一个更复杂的二维手写识别问题,其内部复杂的二维空间结构使得其很难被解析,传统方法的识别效果不佳。随着深度学习在各领域的成功应用,基于深度学习的端到端离线数学公式算法,并在公开数据集上较传统方法获得了显著提升,开辟了全新的数学公式识别框架。然而在线手写数学公式识别框架还未被提出,论文TAP则是首个基于深度学习的端到端在线手写数学公式识别模型,且针对数学公式识别的任务特性提出了多种优化。

公式识别是OCR领域一个非常有挑战性的工作,工作的难点在于它是一个二维的数据,因此无法用传统的CRNN进行识别。

在这里插入图片描述

推荐大家用于毕业设计。。。。

2 效果展示

这里简单的展示一下效果

在这里插入图片描述

在这里插入图片描述

3 具体实现

在这里插入图片描述

神经网络模型是 Seq2Seq + Attention + Beam Search。Seq2Seq的Encoder是CNN,Decoder是LSTM。Encoder和Decoder之间插入Attention层,具体操作是这样:Encoder到Decoder有个扁平化的过程,Attention就是在这里插入的。具体模型的可视化结果如下

在这里插入图片描述

4 关键代码实现

class Encoder(object):
    """Class with a __call__ method that applies convolutions to an image"""
 
    def __init__(self, config):
        self._config = config
 
 
    def __call__(self, img, dropout):
        """Applies convolutions to the image
        Args:
            img: batch of img, shape = (?, height, width, channels), of type tf.uint8
            tf.uint8 因为 2^8 = 256,所以元素值区间 [0, 255],线性压缩到 [-1, 1] 上就是 img = (img - 128) / 128
        Returns:
            the encoded images, shape = (?, h', w', c')
        """
        with tf.variable_scope("Encoder"):
            img = tf.cast(img, tf.float32) - 128.
            img = img / 128.
 
            with tf.variable_scope("convolutional_encoder"):
                # conv + max pool -> /2
                # 64 个 3*3 filters, strike = (1, 1), output_img.shape = ceil(L/S) = ceil(input/strike) = (H, W)
                out = tf.layers.conv2d(img, 64, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_1_layer", out)
                out = tf.layers.max_pooling2d(out, 2, 2, "SAME")
 
                # conv + max pool -> /2
                out = tf.layers.conv2d(out, 128, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_2_layer", out)
                out = tf.layers.max_pooling2d(out, 2, 2, "SAME")
 
                # regular conv -> id
                out = tf.layers.conv2d(out, 256, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_3_layer", out)
                out = tf.layers.conv2d(out, 256, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_4_layer", out)
                if self._config.encoder_cnn == "vanilla":
                    out = tf.layers.max_pooling2d(out, (2, 1), (2, 1), "SAME")
 
                out = tf.layers.conv2d(out, 512, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_5_layer", out)
                if self._config.encoder_cnn == "vanilla":
                    out = tf.layers.max_pooling2d(out, (1, 2), (1, 2), "SAME")
 
                if self._config.encoder_cnn == "cnn":
                    # conv with stride /2 (replaces the 2 max pool)
                    out = tf.layers.conv2d(out, 512, (2, 4), 2, "SAME")
 
                # conv
                out = tf.layers.conv2d(out, 512, 3, 1, "VALID", activation=tf.nn.relu)
                image_summary("out_6_layer", out)
                if self._config.positional_embeddings:
                    # from tensor2tensor lib - positional embeddings
                    # 嵌入位置信息(positional)
                    # 后面将会有一个 flatten 的过程,会丢失掉位置信息,所以现在必须把位置信息嵌入
                    # 嵌入的方法有很多,比如加,乘,缩放等等,这里用 tensor2tensor 的实现
                    out = add_timing_signal_nd(out)
                    image_summary("out_7_layer", out)
        return out

学长编码的部分采用的是传统的卷积神经网络,该网络主要有6层组成,最终得到[N x H x W x C ]大小的特征。

其中:N表示数据的batch数;W、H表示输出的大小,这里W,H是不固定的,从数据集的输入来看我们的输入为固定的buckets,具体如何解决得到不同解码维度的问题稍后再讲;

C为输入的通道数,这里最后得到的通道数为512。

当我们得到特征图之后,我们需要进行reshape操作对特征图进行扁平化,代码具体操作如下:

N    = tf.shape(img)[0]
H, W = tf.shape(img)[1], tf.shape(img)[2] # image
C    = img.shape[3].value                 # channels
self._img = tf.reshape(img, shape=[N, H*W, C])

当我们在进行解码的时候,我们可以直接运用seq2seq来得到我们想要的结果,这个结果可能无法达到我们的预期。因为这个过程会相应的丢失一些位置信息。

位置信息嵌入(Positional Embeddings)

通过位置信息的嵌入,我不需要增加额外的参数的情况下,通过计算512维的向量来表示该图片的位置信息。具体计算公式如下:

在这里插入图片描述

其中:p为位置信息;f为频率参数。从上式可得,图像中的像素的相对位置信息可由sin()或cos表示。

我们知道,sin(a+b)或cos(a+b)可由cos(a)、sin(a)、cos(b)以及sin(b)等表示。也就是说sin(a+b)或cos(a+b)与cos(a)、sin(a)、cos(b)以及sin(b)线性相关,这也可以看作用像素的相对位置正、余弦信息来等效计算相对位置的信息的嵌入。

这个计算过程在tensor2tensor库中已经实现,下面我们看看代码是怎么进行位置信息嵌入。代码实现位于:/model/components/positional.py。

def add_timing_signal_nd(x, min_timescale=1.0, max_timescale=1.0e4):
    static_shape = x.get_shape().as_list()  # [20, 14, 14, 512]
    num_dims = len(static_shape) - 2  # 2
    channels = tf.shape(x)[-1]  # 512
    num_timescales = channels // (num_dims * 2)  # 512 // (2*2) = 128
    log_timescale_increment = (
        math.log(float(max_timescale) / float(min_timescale)) /
        (tf.to_float(num_timescales) - 1))  # -0.1 / 127
    inv_timescales = min_timescale * tf.exp(
        tf.to_float(tf.range(num_timescales)) * -log_timescale_increment)  # len == 128 计算128个维度方向的频率信息
    for dim in range(num_dims):  # dim == 0; 1
        length = tf.shape(x)[dim + 1]  # 14 获取特征图宽/高
        position = tf.to_float(tf.range(length))  # len == 14 计算x或y方向的位置信息[0,1,2...,13]
        scaled_time = tf.expand_dims(position, 1) * tf.expand_dims(
            inv_timescales, 0)  # pos = [14, 1], inv = [1, 128], scaled_time = [14, 128] 计算频率信息与位置信息的乘积
        signal = tf.concat([tf.sin(scaled_time), tf.cos(scaled_time)], axis=1)  # [14, 256] 合并两个方向的位置信息向量
        prepad = dim * 2 * num_timescales  # 0; 256
        postpad = channels - (dim + 1) * 2 * num_timescales  # 512-(1;2)*2*128 = 256; 0
        signal = tf.pad(signal, [[0, 0], [prepad, postpad]])  # [14, 512] 分别在矩阵的上下左右填充0
        for _ in range(1 + dim):  # 1; 2
            signal = tf.expand_dims(signal, 0)
        for _ in range(num_dims - 1 - dim):  # 1, 0
            signal = tf.expand_dims(signal, -2)
        x += signal  # [1, 14, 1, 512]; [1, 1, 14, 512]
    return x

得到公式图片x,y方向的位置信息后,只需要要将其添加到原始特征图像上即可。

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

5 算法综合效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

项目运行效果:

毕业设计 深度学习的公式识别

<think>好的,我现在需要处理用户关于基于深度学习的医学影像图像识别系统的本科毕业设计请求。首先,用户之前已经问过相关问题,现在可能是在寻求更详细的指导或资料。根据用户提供的系统级指令,我需要确保回答结构清晰,使用正确的中文和LaTeX格式,并生成相关问题。 首先,用户的需求是设计方案、实现方法和参考资料。我应该分步骤来阐述,确保每个部分都详细但不过于复杂,适合本科生水平。需要参考之前提供的引用内容,比如引用[1]提到的细节恢复和伪影抑制,引用[2]中的模型训练和预处理步骤,这些可以整合到系统设计的关键技术部分。 接下来,系统设计流程部分应包括数据准备、模型选择、训练优化和系统实现。数据预处理需要提到医学影像的特点,比如噪声多、对比度低,所以预处理步骤应包括归一化、去噪、增强等,引用[2]中的预处理方法可以支持这一点。模型选择方面,ResNet、U-Net和迁移学习都是常用方法,需要简要解释为什么适合医学影像。训练优化部分可以提到数据增强、损失函数选择,以及引用[1]中的细节恢复策略,可能提升生成图像的质量,进而帮助模型训练。 在实现方法中,要给出具体的步骤,比如使用Python和PyTorch框架,数据预处理代码示例,模型构建示例。这里可能需要写一些代码块,但用户示例中的Python代码是快速排序,所以可能需要调整代码示例为数据加载或模型定义。不过要注意用户是否允许代码示例,根据问题描述,用户需要实现方法,所以代码示例合适。 参考资料部分需要列出权威资源,如经典论文、公开数据集和书籍。注意要推荐适合本科生的资源,比如《深度学习》和《医学图像处理》,以及公开数据集如LIDC-IDRI和BraTS。这些资源可以帮助用户进一步查找资料。 生成的相关问题需要围绕毕业设计可能遇到的挑战,比如数据不足、模型选择、评估指标和伦理问题,这些都是本科生可能遇到的难点,能够帮助他们深入思考。 最后,确保整个回答符合格式要求,行内公式用$...$,独立公式用$$...$$,但当前内容中可能涉及的数学公式较少,但如果有的话要注意正确使用。例如,在模型结构部分可能需要提到损失函数,如交叉熵损失$L = -\sum y_i \log(p_i)$,或者准确率公式等,但如果没有具体公式,可能不需要加入。 检查引用部分是否自然插入,比如在数据预处理部分提到引用[2]的实验结果,或在细节恢复部分引用[1]的策略。同时,确保回答结构清晰,分点明确,语言简洁易懂,适合本科毕业设计的指导需求。</think>以下是为您整理的基于深度学习的医学影像图像识别系统毕业设计完整方案,包含技术路线、实现方法和参考资料: ### 一、系统设计流程 1. **数据准备阶段** - 医学影像特点:存在噪声多、对比度低、标注成本高等问题[^2] - 预处理流程: $$ \text{原始数据} \rightarrow \text{归一化} \rightarrow \text{去噪} \rightarrow \text{数据增强} \rightarrow \text{标准化} $$ - 推荐工具:SimpleITK、OpenCV、Albumentations库 2. **模型选择策略** | 任务类型 | 推荐模型 | 适用场景示例 | |----------------|----------------------|--------------------| | 分类任务 | ResNet/DenseNet | 肺结节良恶性判断 | | 分割任务 | U-Net/Attention U-Net| 肿瘤区域分割 | | 小样本学习 | 迁移学习(VGG16) | 罕见病症识别 | 3. **训练优化要点** - 采用渐进式训练策略:先训练低分辨率图像再逐步提高分辨率[^1] - 使用混合损失函数:$L_{total} = \alpha L_{Dice} + \beta L_{CE}$ - 引入注意力机制:空间注意力+通道注意力模块 ### 二、关键技术实现 **数据增强代码示例**: ```python import albumentations as A transform = A.Compose([ A.RandomRotate90(p=0.5), A.GaussianBlur(p=0.3), A.RandomGamma(gamma_limit=(80,120), p=0.2), A.ElasticTransform(alpha=1, sigma=50, alpha_affine=50, p=0.5) ]) ``` **模型构建示例(PyTorch)**: ```python class MedicalResNet(nn.Module): def __init__(self): super().__init__() self.backbone = models.resnet34(pretrained=True) self.classifier = nn.Sequential( nn.Linear(512, 256), nn.ReLU(), nn.Dropout(0.5), nn.Linear(256, 2)) def forward(self, x): features = self.backbone(x) return self.classifier(features) ``` ### 三、论文写作建议 **创新点设计方向**: 1. 融合多模态数据(CT+病理报告) 2. 开发轻量化移动端部署方案 3. 结合可解释性AI技术(如Grad-CAM) **实验设计要点**: - 评估指标:除准确率外,需包含$Dice\ Score=\frac{2|X \cap Y|}{|X|+|Y|}$等医学专用指标 - 对比实验组:与传统方法(如随机森林)、经典深度学习模型对比 - 消融实验:验证各模块的有效性 ### 四、推荐参考资料 1. **经典论文**: - 《U-Net: Convolutional Networks for Biomedical Image Segmentation》 - 《Attention U-Net: Learning Where to Look for the Pancreas》 2. **公开数据集**: - LIDC-IDRI(肺结节数据集) - BraTS(脑肿瘤分割挑战赛数据) 3. **工具书籍**: - 《深度学习》(Ian Goodfellow著) - 《医学图像处理与分析》(科学出版社)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值