环境:tensorflow2 kaggle
这几天突发奇想,用深度学习训练2次函数。先在网上找找相同的资料这方面资料太少了。大多数如下:
 。
。
给我的感觉就是,用深度学习来做,真的很容易。
网上写出代码分析的比较少。但是也找到了一篇,写的言简意赅,不过我自已训练时,却发现对训练之外的数据,预测的不好。下面分两部分来阐明这一现像与我的思考。
一、代码复现:
(204条消息) tensorflow2.0实现简单曲线拟合_一只双鱼儿的博客-CSDN博客_tensorflow2 曲线拟合
网络结构如下:
  
   - 
    
     
    
    
     
      model = tf.keras.Sequential([
     
    
- 
    
     
    
    
     
          tf.keras.layers.Dense(
      10,input_shape=(
      1,),activation=
      "elu"),
     
    
- 
    
     
    
    
     
          tf.keras.layers.Dense(
      1)
     
    
- 
    
     
    
    
     
      ])
     
    
该文章效果如下:

可以看出,在训练集内效果是很好的,但是博主没有使用训练集外的数据。于是我扩展了预测集,效果如下:

可以发现 ,在[1,5]定义域内,基本就是直线了。
这就很奇怪了,在训练集内是曲线,之外是直线。看网络结构,确实引入了非线性的环节如:activation="elu"。那这个非线性环节究竟有多大用呢?这就引出了第一个问题。
我试着将网络结构改为如下(也就是只保留线性环节):
  
   - 
    
     
    
    
     
      """
     
    
- 
    
     
    
    
     
      model = tf.keras.Sequential([
     
    
- 
    
     
    
    
     
       tf.keras.layers.Dense(10,input_shape=(1,),activation="elu"),
     
    
- 
    
     
    
    
     
       tf.keras.layers.Dense(1)
     
    
- 
    
     
    
    
     
      ])
     
    
- 
    
     
    
    
     
      """
     
    
- 
    
     
    
    
     
      model = tf.keras.Sequential([
     
    
- 
    
     
    
    
     
          tf.keras.layers.Dense(
      10,input_shape=(
      1,)),
     
    
- 
    
     
    
    
     
          tf.keras.layers.Dense(
      1)
     
    
- 
    
     
    
    
     
      ])
     
    
效果如下:


好吧,那第一个问题是解决了。activation="elu"效果是很明显的。
二、为什么在训练集之外,生成了直线?
是过拟合吗?将训练集变成了查表法?
我做了如下实验,这其实是我的第二步(y=ax^2+bx+c+[noise],第一步没保存),用来满足y=x^2已经足够了:
  
   - 
    
     
    
    
     
      ds_x = []
     
    
- 
    
     
    
    
     
      ds_y = []
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      # 生成数据集
     
    
- 
    
     
    
    
     
      ds_x = np.linspace(-
      1,
      1,
      100)
     
    
- 
    
     
    
    
     
      ds_y = 
      5*ds_x**
      2 + 
      9*ds_x + 
      300 + np.random.randn(
      100)*
      0.05
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      class 
      model_x2(tf.keras.Model):
     
    
- 
    
     
    
    
         
      def 
      __init__(
      self):
     
    
- 
    
     
    
    
             
      super(model_x2,self).__init__()
     
    
- 
    
     
    
    
     
              self.layer1   = tf.keras.layers.Dense(
      1)
     
    
- 
    
     
    
    
     
              self.layer1_2 = tf.keras.layers.Dense(
      1)
     
    
- 
    
     
    
    
     
              self.layer2   = tf.keras.layers.Dense(
      1)
     
    
- 
    
     
    
    
             
     
    
- 
    
     
    
    
             
     
    
- 
    
     
    
    
             
     
    
- 
    
     
    
    
             
     
    
- 
    
     
    
    
         
      def 
      call(
      self,in1):
     
    
- 
    
     
    
    
     
              in2  = tf.keras.layers.Multiply()((in1,in1,in1)) 
      #in1 * in1
     
    
- 
    
     
    
    
     
              x    = self.layer1(in2)
     
    
- 
    
     
    
    
     
              x1_2 = self.layer1_2(in1)
     
    
- 
    
     
    
    
     
              x2   = tf.keras.layers.concatenate((x,x1_2))
     
    
- 
    
     
    
    
     
              out  = self.layer2(x2)
     
    
- 
    
     
    
    
             
      return out
     
    
- 
    
     
    
    
         
     
    
- 
    
     
    
    
     
      model = model_x2()  
     
    
- 
    
     
    
    
     
      model.build(input_shape=(
      None,
      1))
     
    
- 
    
     
    
    
     
      model.summary()
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      opt       = tf.keras.optimizers.Adam(learning_rate=
      0.01)
     
    
- 
    
     
    
    
     
      los       = tf.keras.losses.MeanSquaredError()
     
    
- 
    
     
    
    
     
      acc       = tf.keras.metrics.MeanSquaredError()
     
    
- 
    
     
    
    
     
      model.
      compile(optimizer=opt,loss=los,metrics=acc)
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      model.fit(ds_x,ds_y,epochs=
      500)
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #以下就是画图了,将数据集里【-1,1】添加到【-1,3】,多出来的【1,3】示为预测
     
    
- 
    
     
    
    
     
      x = np.linspace(-
      1,
      3,
      20000) 
      #np.array(range(1,100,1))
     
    
- 
    
     
    
    
     
      #y = x**x
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      y_predict = model.predict(x)
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      ds_x = np.linspace(-
      1,
      3,
      100)
     
    
- 
    
     
    
    
     
      ds_y = 
      5*ds_x**
      2 + 
      9*ds_x + 
      300 + np.random.randn(
      100)*
      0.05
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      plt.scatter(ds_x,ds_y)
     
    
- 
    
     
    
    
     
      plt.plot(x,y_predict,
      'r')
     
    
- 
    
     
    
    
     
      plt.show()
     
    
 #以下就是画图了,将数据集里【-1,1】添加到【-1,3】,多出来的【1,3】示为预测
效果如下:

三、结论:
用深度学习的多层结构,拟合非线性数据???
NO,NO,NO
应该手动引用非线性因子。
这不禁让我想起了曾经的日子,我们都知道3极管可以线性放大,但是有没有一种方式可以产生x^2项。当然是可以的,这就涉及到2极管还是3极管。。。的物理公式如下。。。
知道的小伙伴可以在评论区留言。
转载:https://blog.csdn.net/c_1969/article/details/128982216
 
					