def batch_dot(x, y, axes=None, name=None): X = x.tensor Y = y.tensor if isinstance(axes, six.integer_types): axes = (axes, axes) if axes is None: axes = (X.shape.ndims - 1, Y.shape.ndims - 2) PLAIDML_BATCHDOT_TF_BEHAVIOR = os.getenv('PLAIDML_BATCHDOT_TF_BEHAVIOR') if PLAIDML_BATCHDOT_TF_BEHAVIOR: _report_unimplemented('batch_dot') else: # replicate theano/documentation-specified behavior first_dim = edsl.TensorDim() first_idx = edsl.TensorIndex() batch_dim = edsl.TensorDim() batch_idx = edsl.TensorIndex() xdims = edsl.TensorDims(X.shape.ndims) xdims[0] = first_dim xdims[axes[0]] = batch_dim xidxs = edsl.TensorIndexes(X.shape.ndims) xidxs[0] = first_idx xidxs[axes[0]] = batch_idx ydims = edsl.TensorDims(Y.shape.ndims) ydims[0] = first_dim ydims[axes[1]] = batch_dim yidxs = edsl.TensorIndexes(Y.shape.ndims) yidxs[0] = first_idx yidxs[axes[1]] = batch_idx odims = [xdims[N] for N in range(len(xdims)) if N != axes[0] ] + [ydims[N] for N in range(1, len(ydims)) if N != axes[1]] oidxs = [xidxs[N] for N in range(len(xidxs)) if N != axes[0] ] + [yidxs[N] for N in range(1, len(yidxs)) if N != axes[1]] X.bind_dims(*xdims) Y.bind_dims(*ydims) O = edsl.TensorOutput(*odims) O[oidxs] += X[xidxs] * Y[yidxs] if len(odims) == 1: O = plaidml_op.expand_dims(O, 1) return _KerasNode('batch_dot', tensor=O)
def one_hot(indices, num_classes): #Note: does not error check for entries in indices that are >= num_classes count = variable(np.array(range(num_classes)), dtype='int32').tensor I = indices.tensor I_ndims = I.shape.ndims I_dims = edsl.TensorDims(I_ndims) I_idxs = edsl.TensorIndexes(I_ndims) C = edsl.TensorDim() c = edsl.TensorIndex() O_dims = I_dims + [C] O_idxs = I_idxs + [c] I.bind_dims(*I_dims) count.bind_dims(C) O = edsl.TensorOutput(*O_dims) O[O_idxs] = I[I_idxs] == count[c] return _KerasNode('one_hot', name='one_hot', tensor=O)
def categorical_crossentropy(target, output, from_logits=False): if from_logits: output = softmax(output) elif output.opname != 'softmax': output /= sum(output, axis=(-1,), keepdims=True) output = clip(output, epsilon(), 1.0 - epsilon()) T = target.tensor O = output.tensor ndims = O.shape.ndims fixed_dims = edsl.TensorDims(ndims - 1) fixed_idxs = edsl.TensorIndexes(ndims - 1) Y = edsl.TensorDim() y = edsl.TensorIndex() input_dims = fixed_dims + [Y] O.bind_dims(*input_dims) T.bind_dims(*input_dims) LO = edsl.log(O) TR = edsl.TensorOutput(*fixed_dims) TR[fixed_idxs] += T[fixed_idxs + [y]] * LO[fixed_idxs + [y]] R = -TR return _KerasNode('categorical_crossentropy', tensor=R)
def time_expand(val, ii, t, prev): I = val.tensor ndmo = I.shape.ndims - 1 if (ndmo < 0): raise PlaidMLKerasException('output values must have a batch size dimension') dims = edsl.TensorDims(ndmo) idxs = edsl.TensorIndexes(ndmo) batch_dim = edsl.TensorDim() batch_idx = edsl.TensorIndex() I_dims = [batch_dim] + dims I_idxs = [batch_idx] + idxs I.bind_dims(*I_dims) O_dims = [batch_dim] + [t] + dims O = edsl.TensorOutput(*O_dims) O_idxs = [batch_idx] + [ii] + idxs O[O_idxs] = I[I_idxs] if prev is None: if ii != 0: raise RuntimeError( 'Generating RNN at time step {} with no previous time step'.format(ii)) else: O.use_default(prev.tensor) return _KerasNode('time_expand', name='time_expand', tensor=O)