吴恩达Deep Learning学习笔记——第二课 改善深层神经网络

目录链接:吴恩达Deep Learning学习笔记目录

 1.deep learning 实用层面
 2.优化算法
 3.超参数调整
 4.多分类问题

1. deep learning实用层面

  1.1 Bias and Variance

  为了加速模型的构建,提高模型性能,在训练模型时,一般将数据data划分为训练集验证集、和测试集,训练集用于训练模型内的参数,如W,b;但还有许多超参数(learning rate、网络结构参数,激活函数选择,正则化参数等)是人为设定的,需要通过验证集来对这些超参数进行优化,测试集用于评估模型的泛化能力
  对于training、validation、test的划分比例,在小量数据集上(如10000),可能是6:2:2的比例,但在大规模的数据集下(如1 million),如果按照这个比例来划分,validation、test的数量太大,对于训练数据资源来说是一种浪费,可能我们的划分比例会是95:4:1,划分数据集时,各数据集应该是同分布的。
  什么是偏差(Bias)和方差(Variance)呢?假设数据集如下图所示,a)通过逻辑回归拟合得到一条直线将两类数据分开,将有许多数据被分类错误,这时候称为欠拟合(outfitting),对应高偏差,如果夸张一些,模型预测出的结果可能和瞎猜差不多(50%概率),模型并没有进行充分的训练,所学习到的信息有限;b)则是一种较为合适的分类结果(假设数据分类即是如此),仅有少量的误差;c)当拟合曲线极其曲折时,虽然它将所有训练数据都分类正确,(假设数据真实分布按照b划分),但用新的数据去进行预测的时候,很可能得到错误的结果(如图中绿x),此时成为过拟合(overfitting),对应高偏差;d)采用曲线函数或更高次的函数,可能会出现这种情况,它处于欠拟合状态,但其又将图中两个数据拟合正确,将会使得模型的偏差和方差都很高。


  对于只有两个特征的数据集我们可以用可视化的方法来展现数据的拟合情况,但对于高维的数据,我们无法可视化。此时采用训练误差和验证集误差来进行判别BiasVariance。如下图所示,对于猫和狗的两类图片,我们认为人眼去识别时,识别错误率为0%(最优误差)。①当模型training识别误差为1%、validation识别误差为11%时,模型过拟合,高方差;②模型training识别误差为15%、validation识别误差为16%时,模型欠拟合,高偏差;③模型training识别误差为15%、validation识别误差为30%时,模型不仅高偏差,还高方差;④模型training识别误差为0.5%、validation识别误差为1%时,模型低偏差、低方差,拟合适度。所以,在此,是基于最优误差较小、training和validation同分布的情况下,采用trainin误差与最优误差之间的差别用于判断是否高偏差,而validation误差与最优误差间的差别用于判断是否高方差。
  但是当我们无法获取最优误差或者获得的最优误差较高时,如图片模糊,人眼也无法识别(无法对数据进行标注?),如何判断数据拟合情况?

  1.2 Basic recipe for machine learing

如何优化模型?
    ①通过一个baseline训练结束后,获取到training error,如果偏差过高甚至无法拟合training,解决的方法一般为增加NN的规模(有作用,一般而言,只要模型足够复杂,通常可以很好的拟合training)、花费更多的时间来训练模型(不一定有用)、或者选择其他NN(不一定有用);
   ②当偏差降低到可以接收的范围,获取validation error,当方差过高时,一般选择增加训练数据量(比较难,数据获取不易)、采用正则化项(regularization)、修改模型
   ③重复①②直到找到一个低偏差、低方差的模型。
   balance bias and variance:在机器学习的早期阶段,基本没有什么方法,可以在影响方差时而不影响偏差,影响偏差时而不影响方差,而在deep learning中,人们不太考虑偏差、方差平衡问题,因为增加数据规模、增加模型复杂度,在适当的正则下通常可以构建一个较好的模型,增加数据规模,可以在减小方差的同时,对偏差影响较小。

  1.3 Regularization

  Logistics Regression:
  L2正则:

  L1正则:

   如果采用L1正则,W最终将会是稀疏的。λ为正则化参数,通常设置为较小的数值,以避免过拟合。
  Neural network:
n[l]表示第l层隐藏层的单元数,这个范数矩阵为Frobenius范数,权重参数更新,等式右边第一项中dw代表后向传播中计算得到的W的导数:
F范数是矩阵中各个元素绝对值平方的总和,范数作用参见关于范的知识整理

  1.4 Why regularization reduces overfitting

  ① 当λ设置到足够大时,W将会被”压缩“到足够小,使得某些权值w约等于0,使得某些单元的影响减小,理解为简化了网络结构(实际上隐藏单元还在),从而减小方差;
  ②当λ设置太小时,正则项将不起作用,所以λ需要设置一个合适的值。



  此外,另一种理解方式是,当λ设置到足够大时,W很小,对于激活函数而言,Z将被限制到0附近,在这个区域内,激活函数近似于线性,激活函数就失去了其本该有的性质,神经网络退变接近logistics回归,从而欠拟合。

  1.5 Dropout regularization

   Dropout策略会在每一隐藏层设置单元被保留和丢弃的概率,然后消除到这些节点的连线,最后得到一个简化后的神经网络,对于每个样本,都采用同一个简化后神经网络来训练。


   Dropout方法:Incerted dropout(反向随机失活)
   假设要消除layer=3的隐藏层20%的神经元,设置keep_prob=0.8,即保留80%神经元,通过np.random.rand()函数生成一个[0,1)的随机均匀分布,通过下述第一行代码将会得到一个shape与a3.shape相同向量,向量值均为True或False,True的占比为80%,通过第二行代码即将第三层的输出值消除20%,第三行代码用于补偿被抛弃的20%,维持a3的期望值,当a3输入到下一层时,相当于layer=3层被消除20%神经元。在测试数据时不进行dropout(否则会导致预测结果变得随机,或需要多次预测,增加了计算量),所有神经元都会被启用。

d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
a3 = np.multiply(a3, d3)
a3 /= keep_prob

   dropout能够提升模型性能的原因是:
   ①在训练过程中,每次被随机消除的神经元,其权重不进行更新但保存,可以理解为通过训练不同的子网络来对结果进行投票(随机森林?),提升网络的泛化能力;
   ②由于每次训练被消除的神经元是随机的,最后的输出结果将对各个神经元依赖程度减小,将权重分配到各神经元较为”均匀“(鸡蛋不要放在一个篮子里),起到类似于L2正则的效果。
   其缺点是,①增加了超参数的搜索量(每一层的keep_prob都不同),②明确定义的代价函数每次迭代都是下降的,添加dropout后代价函数不能再被明确定义,因为每次训练的网络都是随机的,每次代价函数都不一样,代价函数很难被计算出来。所以,计算代价函数时需要关闭dropout,然后再打开dropout,以确保代价函数单调递减。

  1.6 Other regularization methods

   ①数据增强(data argumentation):对于图片,可以进行水平翻转,随机翻转后裁剪;对于字符识别,可以通过随机扭曲、翻转、变形等;
   ②early_stopping:绘制迭代次数与(training error、validation error)间关系图,对于validation error一开始是下降的,到某次迭代后开始上升,early_stopping就是在这个epoch停止迭代训练(如early_stopping=100,如发现本次loss相比上一次未降低,则再迭代100次后停止)。一般而言,代价函数、w、b参数是通过训练(SGD、Adam等)来优化,而过拟合问题又是通过超参数搜索(正则化、数据增强等)来解决,再进行正交,而early_stopping在同时优化loss和降低方差两个问题,所以其缺点是,可能会导致停止优化loss后,loss的值没有达到期望范围内,而同时又不希望过拟合。

  1.7 Normalizing

  当特征尺度相差过大时,量级较大的特征在训练过程中可能对于参数的影响较大,从而影响预测结果,标准化可以消除尺度上的差异,使各特征对于参数的影响相近;Normalizeing还可以避免数值问题,加速网络收敛,分析参见神经网络为什么要归一化
  z-score 标准化:x = (x-μ) / σ,第一步均值化,第二步方差归一化,测试集归一化时所使用得μ和σ应与训练集相同,而不是在两个集合上分别计算μ和σ。

  1.8 Vanishing/exploding gradients

  如下图,为一个深层神经网络,假设激活函数为g(z)=z,假设每一层W>1,此时预测结果呈指数级增长,而W<1时,预测结果呈指数级递减,同理W的梯度也呈现相同的趋势,导致梯度变得极大或极小,这被称为梯度消失(弥散)和梯度爆炸,导致网络难以收敛。参见梯度消失和梯度爆炸原因及其解决方案

  1.9 Weight initialization

  既然神经网络容易出现梯度消失和梯度爆炸问题,那么权重W的初始化显得较为重要,否则可能导致无法收敛。为避免这个两个问题,Xavier Glorot在论文中指出两个经验性的准则:①每一层神经元的激活值的均值要保持为0;②每一层激活值得方差保持不变(反向传播,梯度值方差保持不变),则(激活函数为tanh)权值Wl要满足:


  在实现W初始化时仅仅需要:np.random.randn(shape)*np.sqrt(1/n[l-1])randn()函数生成的随机数服从μ=0,σ2=1的正态分布,乘以√(1/n[l-1])后即服从上述公式分布。推导及其他初始化方法见权值初始化 - Xavier和MSRA方法

  1.10 Gradients checking

  (1)梯度的数值逼近

  (2)梯度检验

  先将所有W和b转化为一个大的向量θ=[w1,w2,...,b1,b2,....],再做梯度近似计算:
  注意:①不要用来训练时计算梯度,调试的时候,仅用于检验反向传播梯度计算是否正确,因为计算量太大;②如果代价函数有正则项,梯度检验也应包括正则项;③不要同时与dropout使用;④一种极端情况,w、b初始化在0附近,此时后向传播计算正确,但w、b变大后,后向传播计算可能开始变得不准确,此时,需要在w初始化过程中执行梯度检验,在反复训练网络后再进行梯度检验。

2. 优化算法

 2.1 Mini-batch 梯度下降法

  机器学习是一个极其依赖经验的过程,需要多次的迭代,训练多个模型才能找到合适的那一个。Deep leraning虽然可以用大量级数据来训练,但其训练速度很慢,优化后的快速算法能够大大提高效率。

  向量化能够有效的同时对所有m的样本进行计算,假设m=500 million,那么在执行梯度下降法时,需要处理整个数据集后才能进行一步梯度下降,然后重复,这将是一个缓慢的过程。在梯度下降前先处理一部分数据,能够加速模型的训练。
   如上图,假设有5,000,000个样本,每个mini-batch 1000个样本(batch size),则有5000个mini-batch(即5000个样本子集),然后执行以下算法(伪):
for  t in range(5000):
      forword propagate on X{t} #X{t}指第t个mini-batch,此时同时处理1000个样本
      compute cost J{t}
      backword propagate
      update gradients

  执行上面代码一次,被称为1 epoch,意味着只遍历了一次训练集(即只训练了一次)。如果将Batch法(即全部样本作为一批)和mini-batch法的loss绘制图如下,会发现Batch的loss曲线单调下降,但mini-batch的loss曲线有噪音,这是由于每个mini-batch中数据不同,所以计算出的loss会有波动。

  ①当batch_size = m 时,即为Batch gradient,梯度下降时较为平滑,其缺点是每个epoch的时间过长;

  ②当batch_size = 1 时,即为SGD,梯度下降时较为曲折,其缺点是失去了向量化带来计算加速。

 2.2 指数加权移动平均(EWMA)

  (1)指数加权移动平均(EWMA)

  β=0.9时为红线,β=0.98时为绿线,β=0.5时为黄线:
  ①Vt为t时刻的EWMA值,θt为t时刻的温度值,β是(0,1)之间的权重参数;
  ②当V0=0时,将公式展开后得到
可以看出随时刻往前移动,该时刻的温度值所占的权重呈指数级衰减,也就是说越往前,前面温度对于当前值的预测影响越小,这个式子可以看作是t前各时刻温度与对应指数衰减函数(1-β)βt-1相乘得到;
  ③为什么说EWMA是平均了当前时刻前N=1/(1-β)天?这是因为
明显,0.35 * (1-β)的权重我们觉得它已经足够小,其再往前的数据我们不再考虑,将其忽略;
  ④既然EWMA近似于近10天数据,为何不直接计算近10天的均值呢?首先,直接计算近10天均值,则近10天的数据对当前的影响相同,EWMA则是距离当前时刻越近,则影响越大;其次,EWMA在实现过程中只每次迭代只需要存储Vt,而直接计算近10天均值要存储近10次迭代的梯度值
  (2)EWMA的偏差修正

  实际上,图中绿色的线是经过偏差修正过后的EWMA,未修正的EWMA为紫色曲线,可以看出在时刻前期,未修正的EWMA值偏低,而在时刻后期一致,这是如何造成的呢?
  当V0=0时,θ1=40,通过加权公式得到V1=0.98 * 0+0.02 * 40=8,可以看出其远比40小,这是由于V0=0造成的,类似冷启动问题,所以此时需要将其进行偏差修正:
   经过修正后V1=(0.98 * 0+0.02 * 40)/ 0.02 =40,而当t很大时,βt趋近于0,公式变为原来的公式,所以偏差修正后的公式主要修正了前期的EWMA值。参见指数加权移动平均优化算法之指数移动加权平均

 2.3 Momentum梯度下降法

  如下图所示,采用梯度下降法时,梯度下降并不是平滑下降的,而是来回摆动,当learning_rate过大时,这个摆动的幅度会更大,但learning_rate过下则会导致梯度下降变得很慢,所以我们希望此时在纵轴上学习变慢,减小摆动,但在横轴上获得加速,得到类似低learning_rate下降轨迹,但其下降的速度大于低learning_rate时的梯度下降,采用Momentum能够获得期望的效果:
for t in range(num_mini_batch):
        compute dW,db # all samples in mini_batch
        Vdw = β Vdw + (1 - β) dW
        Vdb = β Vdb + (1 -β) db

        W = W - α Vdw
        b = b - α Vdb
""" 
注:此时以t做为时刻,即计算t时刻的梯度的EWMA值,而不是计算前几层dw来计算当前层dw的EWMA值。
t:0-t,则dW:dW0,dW1,...,dWt,计算前几次迭代的梯度的EWMA代替梯度来更新W
"""

  在平均过程中,纵轴上正负数相互抵消,所以平均数接近于0,减小了纵轴上的摆动;或者说,如果将梯度分开来看,在下降时,下降的方向分解到横轴和纵轴,在纵轴上是相反方向,但在横轴上是相同方向,计算当前迭代次数时的梯度下降方向时,将前几次梯度下降乘上了不用同的权重参与到当前梯度计算,那么,此时的梯度在横轴上将获得前几次梯度的下降累加,纵轴方向上的梯度出现了抵消,从而使得当前梯度摆动减小。
  一般而言β取0.9,就可以达到不错的效果,而且在实际应用中不对公式进行偏差修正,因为10次迭代后,EWMA已经过了初始阶段,不再是一个具有偏差的值,而迭代次数往往大于10。有的文章里,将(1 - β)去掉,得到 Vdw = βVdw + dW,这样的结果就是相当于Vdw缩小了(1 - β)倍,其缺点是,如果你调整了β,那么α也要被调整。

 2.4 RMSprop (root mean square prop)

  RMSprop能够起到同Momentum一样的作用,减小摆动幅度。
for t in range(num_mini_batch):
        compute dW,db # all samples in mini_batch
        Sdw = β Sdw + (1 - β) (dW)^2
        Sdb = β Sdb + (1 -β) (db)^2

        W = W - α dw/(ε+√Sdw)
        b = b - α db/(ε+√Sdb)
"""√:表示开方"""

  RMSprop(绿线)与Momentum(红线)的区别是,在计算EWMA值时将dW放大,计算EWMA值得结果就是,相对而言,在某个维度方向上的梯度dW较大时,说明此时摆动幅度较大,梯度更新时除以一个较大的值可以减缓这一维度梯度下降的幅度;而当某个维度梯度dW较小时,能基本保持其下降幅度,以此来消除摆动。此外,梯度更新时分母上增加ε是为了避免数值问题(Sdw出现0时)。

 2.5 Adam optimization

  Adam结合了Momentum和RMSprop

一般而言,β1默认0.9,β20.999,ε默认10-8,可以得到不错的效果。

 2.6 Learning rate decay

  一种加快训练的方法就是,在梯度下降初始时,learning_rate大一些,初始时梯度下降很快,在接近最优解时learning_rate小一些,避免越过最优解,更新后的值仅仅在最优解附近小范围内摆动;如果保持learning_rate不变,更新后的值一直在最优解附近较大的范围内摆动。

learning_rate衰减:
learning_rate其他衰减方式:

 2.7 The problem of local optima

  在Deep learning早期,人们往往担心,优化算法会陷在极差的局部最优解,但随着研究的深入,人们对局部最优解有了新的认识。


在高维空间中(假设20000维),如果直接陷入到一个局部最优中去,这个局部所有维度都是凸的,这个概率很小,实际上,我们时常遇到的梯度为0的点是鞍点,即该处每个维度的函数可能凸、可能凹,这个概率远比局部最优大。而在梯度为0或接近0的区域,会导致学习速度变慢。
所以,①不太可能陷入局部最优;②平缓段,学习速度很慢,而Momentum或是RMSprop,Adam这样的算法能够加速这一过程。

3. 超参数调整

 3.1 Hyperparameters

(1)超参数搜索策略
  超参数调整是Deep learning的难点之一,你需要调整大量的超参数,如learning_rate、Momentum的β,Adam的β1 β2 ε、网络层数、单元数、learning_rate衰减参数、batch size等等。但其中一些参数相对而言会更为重要,比如learning_rate,其次batch size、β、单元数,再次网络层数、learning_rate衰减参数。
  较早的参数调整中,使用的搜索方法是网格搜索,当参数量很少的时,这个方法很实用。但在Deep learning中,一般在参数范围内取随机点,这样做的原因是,你很难确定哪一些超参数会比其他参数更重要。如下图,总的搜索点都是25个,如果采用传统的网格搜索,那么一个参数只搜索了5次独立的值,而在随机网格搜索中,一个每个参数维度都搜索了25次独立的值,而此时计算量并未增加,这样找到效果最好的值的概率似乎更大一些。

超参数取值搜索时的另一个有效的方式是,先在大范围内搜索出较优的值,再在较优值附近范围取更为密集的点来进行筛选(由粗到细的策略)。

(2)超参数搜索取值范围及其标尺
  随机网格搜索能够提升超参数搜索效率,但并不是在有效值范围内取值,而对于超参数的搜索,其搜索范围及标尺很重要。例如,对于网络层数和单元数,网络层数取值范围较小,且为整数,可能你可以遍历所有Layers,而单元数则采用随机取值的方式。
  但是这种方法对于某些超参数不适用,如learning_rate,假设你怀疑其最小值是0.0001,最大值为1,然后在这个范围内随机取值,结果就是0.1-1之间的数占了90%,0.0001-0.1之间只有10%的搜索量,这样是不合理的。如果采用对数标尺,数据跨度为0.0001,0.001,0.01,0.1,1,再进行随机取值,那么随机值就会均匀的分布在各个标尺区间,这样的数据搜索更为合理,数据分布更为均匀。
  另一个例子是给β取值,β再越接近0.999时,对细微的变化变得很敏感,所以在接近0.999的区间内,需要更为密集的取值。

 3.2 Batch Normalization

(1)归一化激活函数输入值Z
  Batch Normalization能够使得超参数搜索变得更加容易,使神经网络对超参数得选择更加稳定,超参数得范围更大,效果更好,也会使得深层网络得训练更容易。
  对于单层网络,进行归一化X = (X - μ) / σ后,使得各个维度的数据量级相近,也就是是”扁平“的数据变得”圆润“,这样得好处是梯度下降算法表现更好,收敛速度更快。那么问题来了,对于深层网络,仅仅将输入数据X进行归一化,那么,经过多层传导后输出得A是否还是”圆润“得呢?大概率会不再”圆润“,那么对每一层输出A都进行归一化以加速训练呢?实际上,在应用中通常是对Z进行归一化,再输入给激活函数(为啥是Z不是A,A不服气)。

  Z归一化后,Z的每一个分量均值都为0,方差都为1;为了更好的利用激活函数的非线性,我们并不想所有z的分布都是均值0方差1,也许不同的分布会有意想不到的效果,所以要对归一化后的Z进行重构,重构里的参数是要学习的参数γ(设置方差)和β(设置均值),在梯度下降中,如同更新权重一样更新。其他分析参见批归一化(Batch Normalization)详细解释笔记

(2)神经网络中拟合Batch Norm
  hidden layer中Z的归一化参数学习,类似权重W,b的学习:

(3)为什么Batch Norm有效
  ①输入X归一化后变得”圆润“,加速学习,而hidden layers中Z的Batch Norm也起到了类似的作用;
  ②Batch Norm可以使权重比你的网络更滞后或更深层,为什么?
    测试集数据分布改变,无法准确预测,参见covariate shift现象的解释
    每一层的Z由于其前面layers的参数更新,每次输出的Z的分布是变化的,在经过归一化后,至少其均值和方差保持稳定为训练好后的γ、β,限制了前面layers的参数更新,减少了输入值分布改变带来的问题。
    即使前面的层保持学习,由于Bath Norm使得输入的值变得更稳定(变化较小),迫使了后面的层在前面层参数改变后依然能适应,或者说减弱了后层参数对前层参数的依赖,使得每一层都需要自己学习,与其他层相对独立。
  ③正则化作用。在对Z进行Batch Norm时,因为只是在mini-bacth上计算均值和方差,而不是整个数据集,所以相当于添加了一些噪音给了每一层的激活函数,迫使后面的单元不过分依赖任何一个hidden unit(类似dropout?)起到了轻微的正则化效果。
(3)测试集中Batch Norm
  由于在进行Batch Norm时,计算均值和方差只是在mini-batch中计算的,在训练集中,训练时,单独计算每个mini-batch是没有问题的,因为最终参数会进行更新,参数是基于各个mini-batch的归一化数据学习到的,综合考虑了各个mini-batch(并不是整个数据集的mini-batch)。所以在预测测试集时,我们既不能单独计算每个mini-batch的均值和方差,如此每个mini-batch将会是”独立分布的“数据集用于预测;为了保持Batch Norm时的数据量与训练集相同,也不能计算整个测试集的均值和方差。为了将各个mini-batch的均值和方差联系起来,采用EWMA来对各个mini-batch的均值和方差进行追踪。

4. 多分类问题

 4.1 Softmax regression

  emm...阅图理解。

    softmax层的梯度:

  第二部分的课程笔记到此结束,笔记中有的是自己的理解也不知道对不对,有的还不是很清楚,之后慢慢修改...
  大佬的优化方法解析深度学习中优化方法

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

推荐阅读更多精彩内容