File size: 4,242 Bytes
05c9ac2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
using System.Linq;
namespace Unity.MLAgents.Sensors
{
/// <summary>
/// The compression setting for visual/camera observations.
/// </summary>
public enum SensorCompressionType
{
/// <summary>
/// No compression. Data is preserved as float arrays.
/// </summary>
None,
/// <summary>
/// PNG format. Data will be stored in binary format.
/// </summary>
PNG
}
/// <summary>
/// A description of the compression used for observations.
/// </summary>
/// <remarks>
/// Most ISensor implementations can't take advantage of compression,
/// and should return CompressionSpec.Default() from their ISensor.GetCompressionSpec() methods.
/// Visual observations, or mulitdimensional categorical observations (for example, image segmentation
/// or the piece types in a match-3 game board) can use PNG compression reduce the amount of
/// data transferred between Unity and the trainer.
/// </remarks>
public struct CompressionSpec
{
internal SensorCompressionType m_SensorCompressionType;
/// <summary>
/// The compression type that the sensor will use for its observations.
/// </summary>
public SensorCompressionType SensorCompressionType
{
get => m_SensorCompressionType;
}
internal int[] m_CompressedChannelMapping;
/// <summary>
/// The mapping of the channels in compressed data to the actual channel after decompression.
/// </summary>
/// <remarks>
/// The mapping is a list of integer index with the same length as
/// the number of output observation layers (channels), including padding if there's any.
/// Each index indicates the actual channel the layer will go into.
/// Layers with the same index will be averaged, and layers with negative index will be dropped.
/// For example, mapping for CameraSensor using grayscale and stacking of two: [0, 0, 0, 1, 1, 1]
/// Mapping for GridSensor of 4 channels and stacking of two: [0, 1, 2, 3, -1, -1, 4, 5, 6, 7, -1, -1]
/// </remarks>
public int[] CompressedChannelMapping
{
get => m_CompressedChannelMapping;
}
/// <summary>
/// Return a CompressionSpec indicating possible compression.
/// </summary>
/// <param name="sensorCompressionType">The compression type to use.</param>
/// <param name="compressedChannelMapping">Optional mapping mapping of the channels in compressed data to the
/// actual channel after decompression.</param>
public CompressionSpec(SensorCompressionType sensorCompressionType, int[] compressedChannelMapping = null)
{
m_SensorCompressionType = sensorCompressionType;
m_CompressedChannelMapping = compressedChannelMapping;
}
/// <summary>
/// Return a CompressionSpec indicating no compression. This is recommended for most sensors.
/// </summary>
/// <returns></returns>
public static CompressionSpec Default()
{
return new CompressionSpec
{
m_SensorCompressionType = SensorCompressionType.None,
m_CompressedChannelMapping = null
};
}
/// <summary>
/// Return whether the compressed channel mapping is "trivial"; if so it doesn't need to be sent to the
/// trainer.
/// </summary>
/// <returns></returns>
internal bool IsTrivialMapping()
{
var mapping = CompressedChannelMapping;
if (mapping == null)
{
return true;
}
// check if mapping equals zero mapping
if (mapping.Length == 3 && mapping.All(m => m == 0))
{
return true;
}
// check if mapping equals identity mapping
for (var i = 0; i < mapping.Length; i++)
{
if (mapping[i] != i)
{
return false;
}
}
return true;
}
}
}
|