Concatenate tensors along a dimension. See tf.concat. Args: labeled_tensors: A list of input LabeledTensors. axis_name: The name of the axis along which to concatenate. name: Optional op name. Returns: The concatenated tensor. The coordinate labels for the concatenation
(labeled_tensors, axis_name, name=None)
| 147 | tc.Collection(core.LabeledTensorLike), string_types, |
| 148 | tc.Optional(string_types)) |
| 149 | def concat(labeled_tensors, axis_name, name=None): |
| 150 | """Concatenate tensors along a dimension. |
| 151 | |
| 152 | See tf.concat. |
| 153 | |
| 154 | Args: |
| 155 | labeled_tensors: A list of input LabeledTensors. |
| 156 | axis_name: The name of the axis along which to concatenate. |
| 157 | name: Optional op name. |
| 158 | |
| 159 | Returns: |
| 160 | The concatenated tensor. |
| 161 | The coordinate labels for the concatenation dimension are also concatenated, |
| 162 | if they are available for every tensor. |
| 163 | |
| 164 | Raises: |
| 165 | ValueError: If fewer than one tensor inputs is provided, if the tensors |
| 166 | have incompatible axes, or if `axis_name` isn't the name of an axis. |
| 167 | """ |
| 168 | with ops.name_scope(name, 'lt_concat', labeled_tensors) as scope: |
| 169 | labeled_tensors = [ |
| 170 | core.convert_to_labeled_tensor(lt) for lt in labeled_tensors |
| 171 | ] |
| 172 | |
| 173 | if len(labeled_tensors) < 1: |
| 174 | raise ValueError('concat expects at least 1 tensor, but received %s' % |
| 175 | labeled_tensors) |
| 176 | |
| 177 | # All tensors must have these axes. |
| 178 | axes_0 = labeled_tensors[0].axes |
| 179 | axis_names = list(axes_0.keys()) |
| 180 | |
| 181 | if axis_name not in axis_names: |
| 182 | raise ValueError('%s not in %s' % (axis_name, axis_names)) |
| 183 | |
| 184 | shared_axes = axes_0.remove(axis_name) |
| 185 | |
| 186 | tensors = [labeled_tensors[0].tensor] |
| 187 | concat_axis_list = [axes_0[axis_name]] |
| 188 | for labeled_tensor in labeled_tensors[1:]: |
| 189 | current_shared_axes = labeled_tensor.axes.remove(axis_name) |
| 190 | if current_shared_axes != shared_axes: |
| 191 | # TODO(shoyer): add more specific checks about what went wrong, |
| 192 | # including raising AxisOrderError when appropriate |
| 193 | raise ValueError('Mismatched shared axes: the first tensor ' |
| 194 | 'had axes %r but this tensor has axes %r.' % |
| 195 | (shared_axes, current_shared_axes)) |
| 196 | |
| 197 | # Accumulate the axis labels, if they're available. |
| 198 | concat_axis_list.append(labeled_tensor.axes[axis_name]) |
| 199 | tensors.append(labeled_tensor.tensor) |
| 200 | |
| 201 | concat_axis = core.concat_axes(concat_axis_list) |
| 202 | concat_dimension = axis_names.index(axis_name) |
| 203 | concat_tensor = array_ops.concat(tensors, concat_dimension, name=scope) |
| 204 | values = list(axes_0.values()) |
| 205 | concat_axes = (values[:concat_dimension] + [concat_axis] + |
| 206 | values[concat_dimension + 1:]) |