如何制作自定义的Keras损失函数来调用另一个函数?

时间:2019-03-26 07:12:10

标签: python tensorflow machine-learning optimization keras

我是keras /张量流的新手,我曾尝试在StackOverFlow上使用一些答案,但没有一个对我有用。也许对我来说这是不正确的实现,但我进行了很多搜索,但似乎没有任何效果。

我的代码的基本目标是创建一个神经网络,以优化围绕升/降系数的机翼设计,该神经网络仅使用迎角值。为了说服,输入和除输出基本上是相同的,但是损失函数是唯一的,因为它测试了期望值和输出的升/降系数的alpha值,然后将两者相减,以查看是否有改善。使用改善值,损失等于改善的1分频,因为大的改善将意味着较小的损失。另外,如果结果为负,则我有一个if语句返回高价值损失。另外,我使用的是google colab,因此有时导入的代码位于不同的代码块中。

航空模拟:

%cd OpenAeroStruct

from __future__ import division, print_function
import numpy as np

from openaerostruct.geometry.utils import generate_mesh

from openaerostruct.integration.aerostruct_groups import AerostructGeometry, AerostructPoint

from openmdao.api import IndepVarComp, Problem, Group
from openaerostruct.utils.constants import grav_constant

# Create a dictionary to store options about the surface
mesh_dict = {'num_y' : 5,
             'num_x' : 2,
             'wing_type' : 'CRM',
             'symmetry' : True,
             'num_twist_cp' : 5}

mesh, twist_cp = generate_mesh(mesh_dict)

surface = {
            # Wing definition
            'name' : 'wing',        # name of the surface
            'symmetry' : True,     # if true, model one half of wing
                                    # reflected across the plane y = 0
            'S_ref_type' : 'wetted', # how we compute the wing area,
                                     # can be 'wetted' or 'projected'
            'fem_model_type' : 'tube',

            'thickness_cp' : np.array([.1, .2, .3]),

            'twist_cp' : twist_cp,
            'mesh' : mesh,

            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            'CL0' : 0.0,            # CL of the surface at alpha=0
            'CD0' : 0.015,            # CD of the surface at alpha=0

            # Airfoil properties for viscous drag calculation
            'k_lam' : 0.05,         # percentage of chord with laminar
                                    # flow, used for viscous drag
            't_over_c_cp' : np.array([0.15]),      # thickness over chord ratio (NACA0015)
            'c_max_t' : .303,       # chordwise location of maximum (NACA0015)
                                    # thickness
            'with_viscous' : True,
            'with_wave' : False,     # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E' : 70.e9,            # [Pa] Young's modulus of the spar
            'G' : 30.e9,            # [Pa] shear modulus of the spar
            'yield' : 500.e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case
            'mrho' : 3.e3,          # [kg/m^3] material density
            'fem_origin' : 0.35,    # normalized chordwise location of the spar
            'wing_weight_ratio' : 2.,
            'struct_weight_relief' : False,    # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight' : False,
            # Constraints
            'exact_failure_constraint' : False, # if false, use KS function
            }

# Create the problem and assign the model group
prob = Problem()

# Add problem information as an independent variables component
indep_var_comp = IndepVarComp()
indep_var_comp.add_output('v', val=248.136, units='m/s')
indep_var_comp.add_output('alpha', val=5., units='deg')
indep_var_comp.add_output('Mach_number', val=0.84)
indep_var_comp.add_output('re', val=1.e6, units='1/m')
indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
indep_var_comp.add_output('CT', val=grav_constant * 17.e-6, units='1/s')
indep_var_comp.add_output('R', val=11.165e6, units='m')
indep_var_comp.add_output('W0', val=0.4 * 3e5,  units='kg')
indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s')
indep_var_comp.add_output('load_factor', val=1.)
indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

prob.model.add_subsystem('prob_vars',
     indep_var_comp,
     promotes=['*'])

aerostruct_group = AerostructGeometry(surface=surface)

name = 'wing'

# Add tmp_group to the problem with the name of the surface.
prob.model.add_subsystem(name, aerostruct_group)

point_name = 'AS_point_0'

# Create the aero point group and add it to the model
AS_point = AerostructPoint(surfaces=[surface])

prob.model.add_subsystem(point_name, AS_point,
    promotes_inputs=['v', 'alpha', 'Mach_number', 're', 'rho', 'CT', 'R',
        'W0', 'speed_of_sound', 'empty_cg', 'load_factor'])

com_name = point_name + '.' + name + '_perf'
prob.model.connect(name + '.local_stiff_transformed', point_name + '.coupled.' + name + '.local_stiff_transformed')
prob.model.connect(name + '.nodes', point_name + '.coupled.' + name + '.nodes')

# Connect aerodyamic mesh to coupled group mesh
prob.model.connect(name + '.mesh', point_name + '.coupled.' + name + '.mesh')

# Connect performance calculation variables
prob.model.connect(name + '.radius', com_name + '.radius')
prob.model.connect(name + '.thickness', com_name + '.thickness')
prob.model.connect(name + '.nodes', com_name + '.nodes')
prob.model.connect(name + '.cg_location', point_name + '.' + 'total_perf.' + name + '_cg_location')
prob.model.connect(name + '.structural_mass', point_name + '.' + 'total_perf.' + name + '_structural_mass')
prob.model.connect(name + '.t_over_c', com_name + '.t_over_c')

# Set up the problem
prob.setup()


    # Set the alpha in the problem and run analysi
alphas = np.linspace(-5,5)

# Loopo through each alpha

def testvalue(num):
   alphas = np.linspace(num,num)

# Loopo through each alpha
   for alpha in alphas:
       prob['alpha'] = alpha
       prob.run_model()
       value = prob['AS_point_0.wing_perf.CL']/prob['AS_point_0.wing_perf.CD']
       return(value[0])
       break

测试一下是否可以使用机翼:

def testifitworks(totalarray):

  try:
    return testvalue(totalarray)
    print(totalarray)

  except:
    print(totalarray)
    return -100

keras部分:

# Artificial Neural Network



import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import keras.backend as K
# Importing the Keras 
import keras
import tensorflow as tf

# Importing the dataset
dataset = pd.read_csv('letstryadifferentname.csv')
X = dataset.iloc[:, :1].values
y = dataset.iloc[:, 0].values

# Encoding categorical data

# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler() 
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

def newLoss(layer):
  def loss(y_true, y_pred):

    print(y_true)
    print(0)
    if tf.contrib.framework.is_tensor(y_true) or tf.contrib.framework.is_tensor(y_pred):
      print(1)
      if((testifitworks(K.int_shape(y_pred)[0])-testifitworks(K.int_shape(y_true)[0]))<=0):
          print(2)
          return K.abs(100)
      else:
        print(3)
        return K.abs(1/(testifitworks(K.int_shape(y_pred)[0])-testifitworks(K.int_shape(y_true)[0])))
    else:
      print(4)
      if testifitworks((y_pred)[0])-testifitworks((y_true)[0])<=0:
          print(5)      
          return 100
      else:
          print(6)
          return K.abs(1/(testifitworks((y_pred)[0])-testifitworks((y_true)[0])))
    #print(tf.keras.backend.get_value(y_pred))
    #print(tf.shape(y_true)[0])

  return loss                  

  #returning a function




# Importing the Keras libraries and packages
#import keras
from keras.models import Sequential
from keras.layers import Dense


# Initialising the ANN
classifier = Sequential()

# Adding the input layer and the first hidden layer
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu', input_dim = 1))

# Adding the second hidden layer
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu'))

# Adding the output layer
classifier.add(Dense(units = 1, kernel_initializer = 'uniform', activation = 'sigmoid'))

# Compiling the ANN
classifier.compile(optimizer = 'adam', loss = newLoss(classifier), metrics = ['accuracy'])

# Fitting the ANN to the Training set
classifier.fit(X_train, y_train, batch_size = 10, epochs = 10)

我遇到以下错误。任何帮助将不胜感激。

    Tensor("dense_6_target:0", shape=(?, ?), dtype=float32)
0
1
None
None
2
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
    510                 as_ref=input_arg.is_ref,
--> 511                 preferred_dtype=default_dtype)
    512           except TypeError as err:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py in internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, ctx, accept_symbolic_tensors)
   1174     if ret is None:
-> 1175       ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
   1176 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py in _TensorTensorConversionFunction(t, dtype, name, as_ref)
    976         "Tensor conversion requested dtype %s for Tensor with dtype %s: %r" %
--> 977         (dtype.name, t.dtype.name, str(t)))
    978   return t

ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("dense_6_sample_weights:0", shape=(?,), dtype=float32)'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-10-511534c1dbfe> in <module>()
     74 
     75 # Compiling the ANN
---> 76 classifier.compile(optimizer = 'adam', loss = newLoss(classifier), metrics = ['accuracy'])
     77 
     78 # Fitting the ANN to the Training set

/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, **kwargs)
    340                 with K.name_scope(self.output_names[i] + '_loss'):
    341                     output_loss = weighted_loss(y_true, y_pred,
--> 342                                                 sample_weight, mask)
    343                 if len(self.outputs) > 1:
    344                     self.metrics_tensors.append(output_loss)

/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in weighted(y_true, y_pred, weights, mask)
    419             score_array = K.mean(score_array,
    420                                  axis=list(range(weight_ndim, ndim)))
--> 421             score_array *= weights
    422             score_array /= K.mean(K.cast(K.not_equal(weights, 0), K.floatx()))
    423         return K.mean(score_array)

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
    810     with ops.name_scope(None, op_name, [x, y]) as name:
    811       if isinstance(x, ops.Tensor) and isinstance(y, ops.Tensor):
--> 812         return func(x, y, name=name)
    813       elif not isinstance(y, sparse_tensor.SparseTensor):
    814         try:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in _mul_dispatch(x, y, name)
   1076   is_tensor_y = isinstance(y, ops.Tensor)
   1077   if is_tensor_y:
-> 1078     return gen_math_ops.mul(x, y, name=name)
   1079   else:
   1080     assert isinstance(y, sparse_tensor.SparseTensor)  # Case: Dense * Sparse.

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gen_math_ops.py in mul(x, y, name)
   5858   # Add nodes to the TensorFlow graph.
   5859   _, _, _op = _op_def_lib._apply_op_helper(
-> 5860         "Mul", x=x, y=y, name=name)
   5861   _result = _op.outputs[:]
   5862   _inputs_flat = _op.inputs

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
    545                   "%s type %s of argument '%s'." %
    546                   (prefix, dtypes.as_dtype(attrs[input_arg.type_attr]).name,
--> 547                    inferred_from[input_arg.type_attr]))
    548 
    549           types = [values.dtype]

TypeError: Input 'y' of 'Mul' Op has type float32 that does not match type int32 of argument 'x'.

我相信问题在于访问张量中的值,但我现在还不确定。

0 个答案:

没有答案