网络程序设计学习总结

学号:SA16225140
姓名:李豪俊


前言:
为期7周的“网络程序设计”课程即将告一段落,在此提笔写下对于这门课的总结。很遗憾这门课程的时间太短暂,个人感觉还有很多需要学习了解的地方,特别希望自己能够完整地研究透彻课程项目中所涉及地这些技术——对于基础薄弱的我来说有点眼睛不够用了。

对于这一学期的课程,老师将研究方向转向了神经网络方向。这令我有些措手不及,选课之初以为是关于网络开发的学习研究,得知研究方向的变化其实压力很大,但是也很兴奋,希望能够学到新的知识去丰富自己。本科的时候周围一些同学在进行机器学习相关实验的时候,一直就很好奇,也有些畏惧,感觉艰涩难懂。可以说,学习这门课之前,神经网络对我而言是一个非常高深艰涩的学科。所幸在老师的带领下一点点入门,揭开了这个领域的神秘面纱,让我有勇气去探索发现更多不一样的知识,丰富自己的认知。

1 课程目标

基于深度学习神经网络等机器学习技术实现一个医学辅助诊断的专家系统原型,具体切入点为课程项目(项目地址):对血常规检验报告的OCR识别,深度学习与分析,进行诸如预测患者的年龄和性别等工作,研究其中可能存在的联系。通过该项目,学习机器学习的常见算法框架,重点分析神经网路,理解和掌握常用算法框架工具的使用。

2 神经网路

2.1 简介(摘自百度百科)

** 人工神经网络 **(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。

** 人工神经网络 **:是一种应用类似于大脑神经突触联接的结构进行信息处理的数学模型。在工程与学术界也常直接简称为“神经网络”或类神经网络。

2.2 个人认识

提到神经网络,不可避免得说到机器学习。想必都已经听说,AlphaGo大战围棋高手,近日Master在野狐平台斩获50连胜,快棋击败了无数围棋高手,彰显出机器学习的巨大进步与实力。而神经网络作为机器学习一种应用相当广泛的算法,具有非常重要的意义。

对于当前机器学习发展如火如荼的现状,课程中引入神经网络是非常有远见和胆魄的,相当考验教学者与学生。在老师和同学一致努力下,一个复杂高难度高要求的项目在短短7周内从无到有,亲眼见证这一切我感到无比震惊与自豪。当然我们这门课扩展了不只是神经网络的学习,同学们分享了诸如决策树、支持向量积、贝叶斯分类、集成学习等等都让人大开眼界。

神经网络,其计算模型灵感来自动物的中枢神经系统(尤其是脑),并且被用于估计或可以依赖于大量的输入和一般的未知近似函数。在我看来,即是在模仿脑部神经元突触的形成过程,通过不断地刺激(模型训练),发现新的认识(形成模型)。神经网络的一个重要特性是它能够从环境中学习,并把学习的结果分布存储于网络的突触连接中。神经网络的学习是一个过程,在其所处环境的激励下,相继给网络输入一些样本模式,并按照一定的规则(学习算法)调整网络各层的权值矩阵,待网络各层权值都收敛到一定值,学习过程结束。然后我们就可以用生成的神经网络来对真实数据做分类。

如下图,最左一列节点是输入节点,最右列节点是输出节点,中间节点是隐藏节点。该图结构是分层的,隐藏的部分有时候也会分为多个隐藏层。使用的层数非常多就会变成我们平常说的深度学习了。

神经网络模型

3 项目实践

3.1 神经网络实现手写字符识别

这个课程项目的学习算是对于神经网络初步入门,借以了解OCR识别和神经网络的基本概念。在网页端200x200的画布上监听鼠标按下操作绘制图形,点击按钮,获得画布结果,将其抽象为一个20x20的矩阵,并转为1x400的向量作为输入层。

简单的三层模型

这里主要运用前馈神经网络,该结构中不存在回路。而有输出反馈给输入的神经网络称作递归神经网络(RNN)。在这个实验中,我们使用前馈神经网络中经典的BP神经网络来实现手写识别系统。在数据前向传播时候用sigmoid函数作为激发函数。反向传播是数据的训练关键,需要通过计算误差率然后系统根据误差改变网络的权值矩阵和偏置向量。

sigmoid 两种变换函数

详情见 实验楼课程
进一步的学习 反向传播神经网络极简入门

3.2 对血常规检验报告的OCR识别、深度学习与分析

3.2.1 环境配置

  • 操作系统
    优先选择 Ubuntu 14.04
  • 开发配置
# 安装numpy,
sudo apt-get install python-numpy # http://www.numpy.org/
# 安装opencv
sudo apt-get install python-opencv # http://opencv.org/
# 安装OCR和预处理相关依赖
sudo apt-get install tesseract-ocr
sudo pip install pytesseract
sudo apt-get install python-tk
sudo pip install pillow
# 安装Flask框架
sudo pip install Flask
# 安装mongoDB(如果找不到可以先sudo apt-get update)
sudo apt-get install mongodb
sudo service mongodb started
sudo pip install pymongo
# 安装tensorflow,keras框架
sudo pip install tensorflow
sudo pip install keras
  • 运行
cd BloodTestReportOCR
python view.py # upload图像,在浏览器打开http://yourip:8080

3.2.2 结构说明

  • view.py
    使用Flask(轻量级 Web 应用框架),搭配MongoDB,快速构建Web应用
    只通过一个view.py即可处理对于该项目所需提供响应的Web请求
    Web 端上传图片到服务器,通过ImageFilter进行图片优化处理并切割,进行OCR识别,如果是可以识别的图片文件,存入mongodb并返回其fid

  • imageFilter.py
    对图像透视裁剪和OCR识别进行了简单的封装,以便于模块间的交互,规定适当的接口
    1. ocr函数 - 模块主函数返回识别数据
      用于对img进行ocr识别,他会先进行剪切,之后进一步做ocr识别,返回一个json对象 如果剪切失败,则返回None @num 规定剪切项目数
    2. perspect函数做 - 初步的矫正图片
      用于透视image,他会缓存一个透视后的opencv numpy矩阵,并返回该矩阵 透视失败,则会返回None,并打印不是报告 @param 透视参数
      关于param: 参数的形式为[p1, p2, p3 ,p4 ,p5]。 p1,p2,p3,p4,p5都是整型,其中p1必须是奇数。

p1是高斯模糊的参数,p2和p3是canny边缘检测的高低阈值,p4和p5是和筛选有关的乘数。
如果化验报告单放在桌子上时,有的边缘会稍微翘起,产生比较明显的阴影,这种阴影有可能被识别出来,导致定位失败。 解决的方法是调整p2和p3,来将阴影线筛选掉。但是如果将p2和p3调的比较高,就会导致其他图里的黑线也被筛选掉了。 参数的选择是一个问题。 在getinfo.default中设置的是一个较低的阈值,p2=70,p3=30,这个阈值不会屏蔽阴影线。 如果改为p2=70,p3=50则可以屏蔽,但是会导致其他图片识别困难。

就现在来看,得到较好结果的前提主要有三个
化验单尽量平整
图片中应该包含全部的三条黑线
图片尽量不要包含化验单的边缘,如果有的话,请尽量避开有阴影的边缘。

  1. filter函数 - 过滤掉不合格的或非报告图片
    返回img经过透视过后的PIL格式的Image对象,如果缓存中有PerspectivImg则直接使用,没有先进行透视 过滤失败则返回None @param filter参数
  2. autocut函数 - 将图片中性别、年龄、日期和各项目名称数据分别剪切出来
    用于剪切ImageFilter中的img成员,剪切之后临时图片保存在out_path, 如果剪切失败,返回-1,成功返回0 @num 剪切项目数 @param 剪切参数
    剪切出来的图片在BloodTestReportOCR/temp_pics/ 文件夹下
    函数输出为data0.jpg,data1.jpg……等一系列图片,分别是白细胞计数,中性粒细胞记数等的数值的图片。
  • imgproc.py
    将识别的图像进行处理二值化等操作,提高识别率(包括对中文和数字的处理)
    依次进行了,灰度化,二值化,腐蚀,放大,腐蚀,膨胀,直方图均衡化,中值滤波去噪点等操作,返回一个经过处理的图片

  • tf_predict.py
    使用Tensorflow框架进行年龄、性别预测
  • caffe_predict.py
    使用Caffe框架进行年龄、性别预测

  • classifier.py
    使用pHash.py判定裁剪矫正后的报告是否为血常规检验报告,判定裁剪出检测项目的编号
  • pHash.py
    利用离散余弦变换(DCT)获取图片的低频成分,与已有的一张已经裁剪好的标准图片做对比,如果相似度>60%则接受,判定为血常规检测报告
  • config.py
    用于设定数据,当前包括:可识别图片的类型,数据库的地址与端口号,服务器配置地址与端口号,Flask框架Debug模式开关

3.2.3 项目演示

运行.png
上传图片.png
生成报告.png
预测年龄性别.png

3.2.4 项目要点(Code Review)

  • 网页配置
  1. Flask轻量级框架,便于快速开发
    运行方式简洁
app = Flask(__name__, static_url_path="")
if __name__ == '__main__':
        app.run(host=app.config['SERVER_HOST'], port=app.config['SERVER_PORT'])

HTTP(与 Web 应用会话的协议)有许多不同的访问URL方法。默认情况下,路由只回应GET请求,但是通过route()
装饰器传递methods
参数可以改变这个行为。

@app.route('/', methods=['GET', 'POST'])
def index():
        return redirect('/index.html')

关于Flask Restful参见这里

  1. MongoDB非关系型数据库
    操作简单快捷,为WEB应用提供可扩展的高性能数据存储解决方案
# 连接数据库,并获取数据库对象
db = MongoClient(app.config['DB_HOST'], app.config['DB_PORT']).test
c = dict(report_data=report_data,
             content=bson.binary.Binary(content.getvalue()),
             filename=secure_filename(f.name),
             mime=mime)
    db.files.save(c)
  1. Vue
    由大牛尤雨溪开发的JavaScript框架,目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件
    代码示例如下,数据绑定非常简洁
            <table id= "table_left" class="table table-inverse table-hover table-bordered">
                <thead>
                <tr>
                    <th> </th>
                    <th>检测项目</th>
                    <th>结果</th>
                    <th>参考范围</th>
                    <th>单位</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in report_items_left">
                    <td>{{ item.count }}</td>
                    <td>{{ item.name }}</td>
                    <td>
                        <input type="text" v-model="item.value" class="form-control" placeholder="检测值" />
                    </td>
                    <td>{{ item.range }}</td>
                    <td>{{ item.unit }}</td>
                </tr>
                </tbody>
            </table>

新建Vue对象,在methods自定义方法

    var report = new Vue({
        el: '#report',
        data: {
            report_items_left: new Array(),
            report_items_right: new Array(),
        },
        methods: {………………
  1. AJAX
    AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新
    示例代码如下
        $.ajax({
            url: $(this).attr('action'),
            type: 'POST',
            data: new FormData(this),
            processData: false,
            contentType: false
        }).done(function(data) {
            //console.log(data.templates);

            if(data.error == 1)
            {
                alert("图片不合格!");
            }else
            {
                $("#filtered-image").empty().append(data.templates);
            }
        });
  1. CDN
    值得注意的是,我们开发的时候采用CDN加载外部css,js等资源文件
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>BloodTestOCR</title>
    <!-- Jquey load frist-->
    <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <!-- bootstrap.js below is needed if you wish to zoom and view file content 
     in a larger detailed modal dialog -->
    <!-- https://unpkg.com/vue/dist/vue.js -->
    <script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
    <script src="http://static.runoob.com/assets/vue/1.0.11/vue.min.js"></script>
</head>

在我阅读代码,运行测试的时候发现一些载入异常,对于这样的数据源````在某些网络下无法正常加载,会发生功能不能如期运行的BUG,当前使用<script src="http://static.runoob.com/assets/vue/1.0.11/vue.min.js">替换,也可以考虑使用http://cdn.bootcss.com/bootstrap/数据源

  • OCR识别
    主要使用opencv2包进行处理
    1 对输入的图像进行处理,采用Canny算子描绘边缘
# 载入图像,灰度化,开闭运算,描绘边缘
        
        img_sp = self.img.shape
        ref_lenth = img_sp[0] * img_sp[1] * ref_lenth_multiplier
        img_gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
        img_gb = cv2.GaussianBlur(img_gray, (gb_param, gb_param), 0)
        closed = cv2.morphologyEx(img_gb, cv2.MORPH_CLOSE, kernel)
        opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel)
        edges = cv2.Canny(opened, canny_param_lower , canny_param_upper)
![Canny描绘边缘.jpg](http://upload-images.jianshu.io/upload_images/4255156-d262ee72354be2e5.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2 调用CV2模块的findContours提取矩形轮廓,筛选对角线大于阈值的轮廓

# 调用findContours提取轮廓
        contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 筛选出对角线足够大的几个轮廓
        found = []
        for i in range(len(contours)):
            box = getbox(i)
            distance_arr = distance(box)
            if distance_arr > ref_lenth:
                found.append([i, box])
提取轮廓.png

3 将轮廓变成线,并去除不合适的线

# 将轮廓变为线
        line = []

        for i in found:
            box = i[1]
            point1, point2, lenth = getline(box)
            line.append([point1, point2, lenth])

        # 把不合适的线删去
        if len(line)>3:
            for i in line:
                for j in line:
                    if i is not j:
                        rst = linecmp(i, j)
                        if rst > 0:
                            deleteline(line, j)
                        elif rst < 0:
                            deleteline(line, i)

        #检测出的线数量不对就返回-1跳出
        if len(line) != 3:
            print "it is not a is Report!,len(line) =",len(line)
            return None

# 由三条线来确定表头的位置和表尾的位置
        line_upper, line_lower = findhead(line[2],line[1],line[0])
将轮廓变为线.png

4 透视变换

        #由于需要表格外的数据,所以变换区域需要再向上和向下延伸
        left_axis = line_lower[0] - line_upper[0]
        right_axis = line_lower[1] - line_upper[1]
        line_upper[0] = line_upper[0] - left_axis * 2 / 15
        line_upper[1] = line_upper[1] - right_axis * 2 / 15
        line_lower[0] = line_lower[0] + left_axis * 2 / 15
        line_lower[1] = line_lower[1] + right_axis * 2 / 15

        #设定透视变换的矩阵
        points = np.array([[line_upper[0][0], line_upper[0][1]], [line_upper[1][0], line_upper[1][1]], 
                        [line_lower[0][0], line_lower[0][1]], [line_lower[1][0], line_lower[1][1]]],np.float32)
        standard = np.array([[0,0], [1000, 0], [0, 760], [1000, 760]],np.float32)

        #使用透视变换将表格区域转换为一个1000*760的图
        PerspectiveMatrix = cv2.getPerspectiveTransform(points,standard)
        self.PerspectiveImg = cv2.warpPerspective(self.img, PerspectiveMatrix, (1000, 760))

        #输出透视变换后的图片
        cv2.imwrite(self.output_path + 'region.jpg', self.PerspectiveImg)
透视变换结果.jpg
  • 数据分析(Tensorflow预测性别为例)
    1. 设置参数
    learning_rate = 0.005
    display_step = 100
    n_input = 22

    n_hidden_1_sex = 16
    n_hidden_2_sex = 8
    n_classes_sex = 2
  1. 建立模型
    '''
    建立性别模型
    '''
    x_sex = tf.placeholder("float", [None, n_input])
    y_sex = tf.placeholder("float", [None, n_classes_sex])

    def multilayer_perceptron_sex(x_sex, weights_sex, biases_sex):
        # Hidden layer with RELU activation
        layer_1 = tf.add(tf.matmul(x_sex, weights_sex['h1']), biases_sex['b1'])
        layer_1 = tf.nn.relu(layer_1)
        # Hidden layer with RELU activation
        layer_2 = tf.add(tf.matmul(layer_1, weights_sex['h2']), biases_sex['b2'])
        layer_2 = tf.nn.relu(layer_2)
        # Output layer with linear activation
        out_layer = tf.matmul(layer_2, weights_sex['out']) + biases_sex['out']
        return out_layer

    weights_sex = {
        'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1_sex])),
        'h2': tf.Variable(tf.random_normal([n_hidden_1_sex, n_hidden_2_sex])),
        'out': tf.Variable(tf.random_normal([n_hidden_2_sex, n_classes_sex]))
    }
    biases_sex = {
        'b1': tf.Variable(tf.random_normal([n_hidden_1_sex])),
        'b2': tf.Variable(tf.random_normal([n_hidden_2_sex])),
        'out': tf.Variable(tf.random_normal([n_classes_sex]))
    }
    pred_sex = multilayer_perceptron_sex(x_sex, weights_sex, biases_sex)
  1. 运行测试
    saver = tf.train.Saver()
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        saver.restore(sess, "./model.ckpt")
        print ("load model success!")
        p_sex = sess.run(pred_sex, feed_dict={x_sex: data_predict})
    if p_sex[0][0] > p_sex[0][1]:
        sex_result = 1
    else:
        sex_result = 0
return sex_result

4 总结反思

近70人共同完成这一个项目,相当考验项目管理者的集成能力,这么一个庞大的开发团体,也非常需要软件工程经验对我们进行指导。幸而,孟宁老师坐镇中枢,集成管理整个项目,保证了项目的进展与成功。可以毫不夸张地说,缺少孟宁老师这样的项目管理者,我们几乎无法完成这门课的学习。

正是因为项目的复杂、高难度以及参与人数的庞大,项目的可扩展性相当高。我看到针对项目的每个环节,都有同学提出了各种各样不同的实现方式,没有说给出一个定式。一个开放的实践课程,让我大开眼界。例如,对于预测,同学们提出了CNN、RNN、决策树、向量积等等不一样的实现方式;在对于框架的选择上,也有各种不一样的偏好:Caffee、Tensorflow、Karas。可以说是,“八仙过海,各显神通”,让我见识到了周围同学出色的代码编程以及学习能力,实在佩服。

这门课程对于机器学习的知识面狩猎非常之广,个人零基础,一开始听大神们侃侃而谈就有点迷糊跟不上节奏,因此买了一本周志华老师的《机器学习》自己默默啃着,然而因为下学期5门课程的重压,精力实在有点捉襟见肘,直到现在还没有看完。但是,随着课程的学习,我也简单了解了很多关于机器学习的知识,极大地开拓了眼界,与人谈论机器学习时至少能够搭得上话了吧。(不知道是不是也算有所得了)

需要反省的是,自己做事比较磨蹭,每次有新的想法总会犹豫一下,又对于自己能力有点不自信,故而未曾pr,最后零贡献实在有点难看,希望这些缺点能够改正。

最后在检查的时候,对于页面改善提出了一点看法,根据老师的要求进行了修改,集成Bootstrap上传控件,提交了一个pr #270 完成对于Bootstrap上传插件的集成,总算也不是零贡献了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容

  • 前言 《网络程序设计》的课程已经结束了,一如孟宁老师以往的风格,继高软的“kingke”后,老师给出了“np201...
    没用的伞啊阅读 1,600评论 0 0
  • 美人如画 皎如秋月
    雅丝颜阅读 394评论 2 2
  • 之前发了一条微博,一个南方妹子的偶然评论让我们聊了起来,加了她的关注,她也回关。昨天加了微信,很神奇,哈哈...
    叨叨歪阅读 56评论 0 0
  • 海浪冲刷着指尖, 短暂地重复着涌起褪去。 路灯昏黄, 孑然一身。 走在这漫长的黑夜, 时光匆匆赶路, 悄悄勾住了我...
    朗炽阅读 307评论 0 0
  • R:"盲目的冲动和热血沸腾就越容易失控,越会失去理智的控制,而任凭感性、感觉以及感情来决策巨额的财富走向。这再次证...
    秦圆圆阅读 163评论 0 0