Signals can be given an initialization value at declaration:
signal foo: foo_type := foo_type_value;
Note the := assignment operator which may look a bit counter-intuitive for a signal.
But no, it is not possible to assign 'U' or 'X' to a signal which type is natural because they are not natural values. What you can do, instead, is decide that value 512 is the equivalent of U for your signal and assign it at declaration time:
signal cnt : natural range 0 to 512 := 512;
As this extra value is not supposed to be used after initialization you could (should) add a concurrent assertion to detect unwanted situations:
assert cnt /= 512 report "Ooops! cnt=512" severity warning;
Another option is to use ieee.numeric_std.unsigned instead of natural:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
...
signal cnt : unsigned(8 downto 0) := (others => 'U');
But before using this, be sure you understand the differences. For instance, if you try to decrement your natural cnt while its value is 0 you will get an error while with the unsigned version cnt will silently wrap to "111111111".
naturalis a numeric type. 'U' and 'X' are not possible.