Returns a relaxed (possibly reshaped/upcast-ed) version of value, to be loaded to the given variable. Args: value (ndarray): an numpy array to be loaded to var var (tf.Variable): ignore_mismatch (bool): ignore failures when the value and
(value, var, ignore_mismatch=False)
| 56 | |
| 57 | @staticmethod |
| 58 | def relaxed_value_for_var(value, var, ignore_mismatch=False): |
| 59 | """ |
| 60 | Returns a relaxed (possibly reshaped/upcast-ed) version of value, |
| 61 | to be loaded to the given variable. |
| 62 | |
| 63 | Args: |
| 64 | value (ndarray): an numpy array to be loaded to var |
| 65 | var (tf.Variable): |
| 66 | ignore_mismatch (bool): ignore failures when the value and the |
| 67 | variable does not match. |
| 68 | |
| 69 | Returns: |
| 70 | ndarray: a possibly reshaped or casted version of value. |
| 71 | Returns None if `ignore_mismatch==True` and the value and the variable |
| 72 | mismatch. |
| 73 | """ |
| 74 | assert isinstance(var, tf.Variable) |
| 75 | name = var.op.name |
| 76 | |
| 77 | # check incompatible shape |
| 78 | varshape = tuple(var.get_shape().as_list()) |
| 79 | if varshape != value.shape: |
| 80 | if np.prod(varshape) != np.prod(value.shape): |
| 81 | if ignore_mismatch: |
| 82 | logger.warn( |
| 83 | "Cannot load an array of shape {} into variable '{}' whose shape is {}.".format( |
| 84 | value.shape, name, varshape)) |
| 85 | return None |
| 86 | else: |
| 87 | raise ValueError( |
| 88 | "Trying to load an array of shape {} into variable '{}' whose shape is {}.".format( |
| 89 | value.shape, name, varshape)) |
| 90 | # TODO only allow reshape when shape different by empty axis |
| 91 | logger.warn("The tensor is reshaped from {} to {} when assigned to '{}'".format( |
| 92 | value.shape, varshape, name)) |
| 93 | value = value.reshape(varshape) |
| 94 | |
| 95 | # Be permissive, and allow some common type incompatibility problems |
| 96 | def allow_cast(to_type, from_type): |
| 97 | # to_type: a tf dtype |
| 98 | # from_type: a numpy dtype |
| 99 | from_type = tf.as_dtype(from_type) |
| 100 | |
| 101 | # allow up/down casting between floating points |
| 102 | if from_type.is_floating and to_type.is_floating: |
| 103 | return True |
| 104 | |
| 105 | if from_type.is_integer and to_type.is_integer: |
| 106 | # only allow up-casting between integers |
| 107 | if to_type.min <= from_type.min and to_type.max >= from_type.max: |
| 108 | return True |
| 109 | return False |
| 110 | |
| 111 | if hasattr(value, 'dtype'): |
| 112 | vartype = var.dtype.as_numpy_dtype |
| 113 | if vartype != value.dtype: |
| 114 | msg = "Variable {} has dtype {} but was given a value of dtype {}.".format(name, var.dtype, value.dtype) |
| 115 |